mirror of
https://github.com/bancika/diy-layout-creator
synced 2026-11-13 02:32:09 +10:00
Refactor/maven (#889)
* mavenize * mavenization * mavenization * mavenization * mavenization * mavenization * mavenization * mavenization * mavenization * fix * app framework update * fix lib * lib * fix mavenized * fix mavenized * fix mavenized * fix mavenized * fix mavenized * fix mavenized * fix mavenized * fix mavenized * building for win and linux * Create run.bat * fixes for netlist * cleanup * unit tests * unit tests * configurable high dpi * performance upgrade * performance upgrade * rotate bug * Omit boards, wires, traces, terminals, etc from Spice netlist output * splash version update * optimize libs * optimize libs * updates * mac build maven * ruler optimization, moved images * cleanup * notarization * test workflow * build * Update pom.xml * Update pom.xml * Create README.md * Create test.yml * maven * build
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
package org.diylc;
|
||||
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Suite;
|
||||
import org.junit.runners.Suite.SuiteClasses;
|
||||
|
||||
import org.diylc.plugins.file.BomMakerTest;
|
||||
import org.diylc.presenter.ClassProcessorTest;
|
||||
|
||||
|
||||
@RunWith(Suite.class)
|
||||
@SuiteClasses({BomMakerTest.class, ClassProcessorTest.class})
|
||||
public class AllTests {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package org.diylc.core.gerber;
|
||||
|
||||
import java.awt.Font;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Shape;
|
||||
import java.awt.font.TextLayout;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
import org.junit.Test;
|
||||
import com.bancika.gerberwriter.DataLayer;
|
||||
import com.bancika.gerberwriter.GenerationSoftware;
|
||||
|
||||
import org.diylc.core.gerber.GerberPathRenderer;
|
||||
|
||||
public class GerberPathRendererTest {
|
||||
|
||||
@Test
|
||||
public void testCurveApproximation1() throws IOException {
|
||||
String text = "5pF";
|
||||
String font = "Square721 BT";
|
||||
Shape shape = textToShape(text, font);
|
||||
DataLayer dataLayer = new DataLayer("Copper.Top", false, new GenerationSoftware("v", "a", "ver"));
|
||||
GerberPathRenderer.outputPathArea(shape.getPathIterator(null), dataLayer, 0.1, false, "Conductor");
|
||||
// dataLayer.dumpGerberToFile(font + text + ".gbr");
|
||||
}
|
||||
|
||||
private Shape textToShape(String text, String font) {
|
||||
BufferedImage img = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB);
|
||||
Graphics2D g2d = img.createGraphics();
|
||||
Font f = new Font(font, Font.BOLD, 50);
|
||||
g2d.setFont(f);
|
||||
TextLayout layout = new TextLayout(text, f, g2d.getFontRenderContext());
|
||||
Shape shape = layout.getOutline(AffineTransform.getScaleInstance(1, -1));
|
||||
return shape;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package org.diylc.netlist;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.diylc.netlist.TreeAsciiUtil;
|
||||
|
||||
public class TreeAsciiUtilTest {
|
||||
|
||||
@Test
|
||||
public void testConcatenateMultiLineSerial() {
|
||||
List<String> result = TreeAsciiUtil.concatenateMultiLineSerial("-",
|
||||
Arrays.asList(Arrays.asList("xx", "yy"), Arrays.asList("xxx", "yyy", "aaa")));
|
||||
assertNotNull(result);
|
||||
assertEquals(3, result.size());
|
||||
assertEquals("xx xxx", result.get(0));
|
||||
assertEquals("yy-yyy", result.get(1));
|
||||
assertEquals(" aaa", result.get(2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConcatenateMultiLineSerial_singleInput() {
|
||||
List<List<String>> elementList = Arrays.asList(Arrays.asList("xx", "yy"));
|
||||
List<String> result = TreeAsciiUtil.concatenateMultiLineSerial("-", elementList);
|
||||
assertNotNull(result);
|
||||
assertEquals(Arrays.asList("xx", "yy"), result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConcatenateMultiLineParallel() {
|
||||
List<String> result = TreeAsciiUtil.concatenateMultiLineParallel(
|
||||
Arrays.asList(Arrays.asList("xx", "yy"), Arrays.asList("xxx", "yyy", "aaa")));
|
||||
|
||||
System.out.println("<font face=\"Courier New\">" + String.join("<br>", result) +"</font>");
|
||||
assertNotNull(result);
|
||||
// assertEquals(3, result.size());
|
||||
// assertEquals("xx xxx", result.get(0));
|
||||
// assertEquals("yy-yyy", result.get(1));
|
||||
// assertEquals(" aaa", result.get(2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConcatenateMultiLineParallel_4_lines() {
|
||||
List<String> result = TreeAsciiUtil.concatenateMultiLineParallel(
|
||||
Arrays.asList(Arrays.asList("xx"), Arrays.asList("xx"), Arrays.asList("xx"), Arrays.asList("xx")));
|
||||
|
||||
System.out.println("<font face=\"Courier New\">" + String.join("<br>", result) +"</font>");
|
||||
assertNotNull(result);
|
||||
// assertEquals(3, result.size());
|
||||
// assertEquals("xx xxx", result.get(0));
|
||||
// assertEquals("yy-yyy", result.get(1));
|
||||
// assertEquals(" aaa", result.get(2));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
package org.diylc.plugins.file;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.diylc.core.IDIYComponent;
|
||||
import org.diylc.core.measures.Capacitance;
|
||||
import org.diylc.core.measures.CapacitanceUnit;
|
||||
import org.diylc.utils.BomEntry;
|
||||
import org.diylc.utils.BomMaker;
|
||||
import org.diylc.testcomponents.MockDIYComponent;
|
||||
|
||||
public class BomMakerTest {
|
||||
|
||||
@Test
|
||||
public void testCreateBom() {
|
||||
List<IDIYComponent<?>> components = new ArrayList<IDIYComponent<?>>();
|
||||
MockDIYComponent c1 = new MockDIYComponent();
|
||||
c1.setValue(new Capacitance(3d, CapacitanceUnit.pF));
|
||||
components.add(c1);
|
||||
components.add(new MockDIYComponent());
|
||||
components.add(new MockDIYComponent());
|
||||
List<BomEntry> bom = BomMaker.getInstance().createBom(components);
|
||||
assertNotNull(bom);
|
||||
assertEquals(2, bom.size());
|
||||
Collections.sort(bom, new Comparator<BomEntry>() {
|
||||
|
||||
@Override
|
||||
public int compare(BomEntry o1, BomEntry o2) {
|
||||
return o1.getQuantity().compareTo(o2.getQuantity());
|
||||
}});
|
||||
BomEntry entry1 = bom.get(0);
|
||||
assertEquals("something", entry1.getName());
|
||||
assertEquals(1, (int) entry1.getQuantity());
|
||||
BomEntry entry2 = bom.get(1);
|
||||
assertEquals("something, something", entry2.getName());
|
||||
assertEquals(2, (int) entry2.getQuantity());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
package org.diylc.presenter;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import java.awt.geom.Point2D;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.diylc.core.IDIYComponent;
|
||||
import org.diylc.core.measures.Size;
|
||||
import org.diylc.core.measures.SizeUnit;
|
||||
import org.junit.Test;
|
||||
|
||||
public class CalcUtilsTest {
|
||||
|
||||
@Test
|
||||
public void testRoundToGrid() {
|
||||
Size gridSpacing = new Size(10.0, SizeUnit.px);
|
||||
|
||||
// Test exact grid points
|
||||
assertEquals(10.0, CalcUtils.roundToGrid(10.0, gridSpacing), 0.001);
|
||||
assertEquals(20.0, CalcUtils.roundToGrid(20.0, gridSpacing), 0.001);
|
||||
|
||||
// Test rounding up
|
||||
assertEquals(10.0, CalcUtils.roundToGrid(8.0, gridSpacing), 0.001);
|
||||
assertEquals(20.0, CalcUtils.roundToGrid(16.0, gridSpacing), 0.001);
|
||||
|
||||
// Test rounding down
|
||||
assertEquals(10.0, CalcUtils.roundToGrid(12.0, gridSpacing), 0.001);
|
||||
assertEquals(20.0, CalcUtils.roundToGrid(22.0, gridSpacing), 0.001);
|
||||
|
||||
// Test with different grid spacing
|
||||
Size finerGrid = new Size(5.0, SizeUnit.px);
|
||||
assertEquals(5.0, CalcUtils.roundToGrid(6.0, finerGrid), 0.001);
|
||||
assertEquals(15.0, CalcUtils.roundToGrid(13.0, finerGrid), 0.001);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSnapPointToGrid() {
|
||||
Size gridSpacing = new Size(10.0, SizeUnit.px);
|
||||
Point2D point = new Point2D.Double(12.0, 18.0);
|
||||
|
||||
CalcUtils.snapPointToGrid(point, gridSpacing);
|
||||
|
||||
assertEquals(10.0, point.getX(), 0.001);
|
||||
assertEquals(20.0, point.getY(), 0.001);
|
||||
|
||||
// Test with point exactly on grid
|
||||
point.setLocation(20.0, 30.0);
|
||||
CalcUtils.snapPointToGrid(point, gridSpacing);
|
||||
assertEquals(20.0, point.getX(), 0.001);
|
||||
assertEquals(30.0, point.getY(), 0.001);
|
||||
|
||||
// Test with different grid spacing
|
||||
Size finerGrid = new Size(5.0, SizeUnit.px);
|
||||
point.setLocation(13.0, 28.0);
|
||||
CalcUtils.snapPointToGrid(point, finerGrid);
|
||||
assertEquals(15.0, point.getX(), 0.001);
|
||||
assertEquals(30.0, point.getY(), 0.001);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFindClosestMultiplierOf() {
|
||||
Size factor = new Size(1.0, SizeUnit.mm);
|
||||
Size target = new Size(3.5, SizeUnit.mm);
|
||||
int step = 1;
|
||||
|
||||
Size result = CalcUtils.findClosestMultiplierOf(factor, target, step);
|
||||
assertEquals(4.0, result.getValue(), 0.001);
|
||||
assertEquals(SizeUnit.mm, result.getUnit());
|
||||
|
||||
// Test with different step
|
||||
result = CalcUtils.findClosestMultiplierOf(factor, target, 2);
|
||||
assertEquals(4.0, result.getValue(), 0.001);
|
||||
|
||||
// Test with different factor
|
||||
factor = new Size(0.5, SizeUnit.mm);
|
||||
result = CalcUtils.findClosestMultiplierOf(factor, target, step);
|
||||
assertEquals(3.5, result.getValue(), 0.001);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSnapPointToObjects() {
|
||||
Size gridSpacing = new Size(10.0, SizeUnit.px);
|
||||
Point2D point = new Point2D.Double(12.0, 18.0);
|
||||
|
||||
// Create mock components
|
||||
IDIYComponent<?> component1 = mock(IDIYComponent.class);
|
||||
IDIYComponent<?> component2 = mock(IDIYComponent.class);
|
||||
|
||||
// Setup component1 with a sticky point near our test point
|
||||
when(component1.getControlPointCount()).thenReturn(1);
|
||||
when(component1.isControlPointSticky(0)).thenReturn(true);
|
||||
when(component1.getControlPoint(0)).thenReturn(new Point2D.Double(10.0, 20.0));
|
||||
|
||||
// Setup component2 with a non-sticky point
|
||||
when(component2.getControlPointCount()).thenReturn(1);
|
||||
when(component2.isControlPointSticky(0)).thenReturn(false);
|
||||
when(component2.getControlPoint(0)).thenReturn(new Point2D.Double(11.0, 19.0));
|
||||
|
||||
List<IDIYComponent<?>> components = Arrays.asList(component1, component2);
|
||||
|
||||
// Test snapping to sticky point
|
||||
CalcUtils.snapPointToObjects(point, gridSpacing, null, components);
|
||||
assertEquals(10.0, point.getX(), 0.001);
|
||||
assertEquals(20.0, point.getY(), 0.001);
|
||||
|
||||
// Test not snapping when point is too far
|
||||
point.setLocation(25.0, 25.0);
|
||||
CalcUtils.snapPointToObjects(point, gridSpacing, null, components);
|
||||
assertEquals(25.0, point.getX(), 0.001);
|
||||
assertEquals(25.0, point.getY(), 0.001);
|
||||
|
||||
// Test not snapping to non-sticky points
|
||||
point.setLocation(15.0, 23.0); // Changed coordinates to be further from sticky point
|
||||
CalcUtils.snapPointToObjects(point, gridSpacing, null, components);
|
||||
assertEquals(15.0, point.getX(), 0.001);
|
||||
assertEquals(23.0, point.getY(), 0.001);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPointsMatch() {
|
||||
Point2D point1 = new Point2D.Double(10.0, 20.0);
|
||||
Point2D point2 = new Point2D.Double(10.0, 20.0);
|
||||
|
||||
// Test exact match
|
||||
assertTrue(CalcUtils.pointsMatch(point1, point2, 0.001));
|
||||
|
||||
// Test within delta
|
||||
point2.setLocation(10.1, 20.1);
|
||||
assertTrue(CalcUtils.pointsMatch(point1, point2, 0.2));
|
||||
|
||||
// Test outside delta
|
||||
assertFalse(CalcUtils.pointsMatch(point1, point2, 0.05));
|
||||
|
||||
// Test x coordinate outside delta
|
||||
point2.setLocation(11.0, 20.0);
|
||||
assertFalse(CalcUtils.pointsMatch(point1, point2, 0.5));
|
||||
|
||||
// Test y coordinate outside delta
|
||||
point2.setLocation(10.0, 21.0);
|
||||
assertFalse(CalcUtils.pointsMatch(point1, point2, 0.5));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
package org.diylc.presenter;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.diylc.common.PropertyWrapper;
|
||||
import org.diylc.presenter.ComponentProcessor;
|
||||
import org.diylc.testcomponents.MockDIYComponent;
|
||||
|
||||
|
||||
public class ClassProcessorTest {
|
||||
|
||||
@Test
|
||||
public void testExtractProperties() {
|
||||
List<PropertyWrapper> properties = ComponentProcessor.getInstance().extractProperties(MockDIYComponent.class);
|
||||
assertNotNull(properties);
|
||||
assertEquals(5, properties.size());
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,219 @@
|
||||
package org.diylc.presenter;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import java.awt.Point;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.diylc.common.ComponentType;
|
||||
import org.diylc.common.IComponentTransformer;
|
||||
import org.diylc.common.PropertyWrapper;
|
||||
import org.diylc.components.AbstractComponent;
|
||||
import org.diylc.core.CreationMethod;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
import org.diylc.core.VisibilityPolicy;
|
||||
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.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
public class ComponentProcessorTest {
|
||||
|
||||
private ComponentProcessor processor;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
processor = ComponentProcessor.getInstance();
|
||||
}
|
||||
|
||||
@ComponentDescriptor(
|
||||
name = "Test Component",
|
||||
category = "Test",
|
||||
author = "Test Author",
|
||||
description = "Test Description",
|
||||
instanceNamePrefix = "TEST",
|
||||
creationMethod = CreationMethod.POINT_BY_POINT,
|
||||
zOrder = IDIYComponent.COMPONENT,
|
||||
flexibleZOrder = false,
|
||||
bomPolicy = BomPolicy.NEVER_SHOW,
|
||||
autoEdit = false,
|
||||
enableCache = true,
|
||||
keywordPolicy = KeywordPolicy.SHOW_VALUE,
|
||||
keywordTag = "",
|
||||
enableDatasheet = false,
|
||||
datasheetCreationStepCount = 0
|
||||
)
|
||||
public static class TestComponent extends AbstractComponent<Object> {
|
||||
private String testProperty = "test";
|
||||
private int numericProperty = 42;
|
||||
|
||||
@EditableProperty
|
||||
public String getTestProperty() {
|
||||
return testProperty;
|
||||
}
|
||||
|
||||
public void setTestProperty(String value) {
|
||||
this.testProperty = value;
|
||||
}
|
||||
|
||||
@EditableProperty(name = "Number")
|
||||
public int getNumericProperty() {
|
||||
return numericProperty;
|
||||
}
|
||||
|
||||
public void setNumericProperty(int value) {
|
||||
this.numericProperty = value;
|
||||
}
|
||||
|
||||
// Implement required methods
|
||||
@Override
|
||||
public void drawIcon(java.awt.Graphics2D g2d, int width, int height) {}
|
||||
|
||||
@Override
|
||||
public void draw(java.awt.Graphics2D g2d, org.diylc.core.ComponentState componentState,
|
||||
boolean outlineMode, org.diylc.core.Project project,
|
||||
org.diylc.core.IDrawingObserver drawingObserver) {}
|
||||
|
||||
@Override
|
||||
public Point2D getControlPoint(int index) {
|
||||
return new Point(0, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isControlPointSticky(int index) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getControlPointCount() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setControlPoint(Point2D point, int index) {}
|
||||
|
||||
@Override
|
||||
public VisibilityPolicy getControlPointVisibilityPolicy(int index) {
|
||||
return VisibilityPolicy.WHEN_SELECTED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getValue() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValue(Object value) {}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExtractComponentType() {
|
||||
ComponentType type = processor.extractComponentTypeFrom(TestComponent.class);
|
||||
|
||||
assertNotNull("Component type should not be null", type);
|
||||
assertEquals("Test Component", type.getName());
|
||||
assertEquals("Test", type.getCategory());
|
||||
assertEquals("Test Author", type.getAuthor());
|
||||
assertEquals("Test Description", type.getDescription());
|
||||
assertEquals("TEST", type.getNamePrefix());
|
||||
assertEquals(TestComponent.class, type.getInstanceClass());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExtractProperties() {
|
||||
List<PropertyWrapper> properties = processor.extractProperties(TestComponent.class);
|
||||
|
||||
assertNotNull("Properties list should not be null", properties);
|
||||
assertEquals("Should have 3 properties", 3, properties.size());
|
||||
|
||||
// Find and verify testProperty
|
||||
PropertyWrapper testProp = findPropertyByName(properties, "TestProperty");
|
||||
assertNotNull("TestProperty should exist", testProp);
|
||||
assertEquals(String.class, testProp.getType());
|
||||
|
||||
// Find and verify numericProperty
|
||||
PropertyWrapper numProp = findPropertyByName(properties, "Number");
|
||||
assertNotNull("Number property should exist", numProp);
|
||||
assertEquals(int.class, numProp.getType());
|
||||
|
||||
// Find and verify name property from AbstractComponent
|
||||
PropertyWrapper nameProp = findPropertyByName(properties, "Name");
|
||||
assertNotNull("Name property should exist", nameProp);
|
||||
assertEquals(String.class, nameProp.getType());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetMutualSelectionProperties() throws Exception {
|
||||
TestComponent comp1 = new TestComponent();
|
||||
TestComponent comp2 = new TestComponent();
|
||||
|
||||
// Set same values
|
||||
comp1.setTestProperty("same");
|
||||
comp2.setTestProperty("same");
|
||||
comp1.setNumericProperty(42);
|
||||
comp2.setNumericProperty(42);
|
||||
comp1.setName("same name");
|
||||
comp2.setName("same name");
|
||||
|
||||
List<PropertyWrapper> mutualProps = processor.getMutualSelectionProperties(
|
||||
Arrays.asList(comp1, comp2));
|
||||
|
||||
assertNotNull("Mutual properties should not be null", mutualProps);
|
||||
assertEquals("Should have 3 mutual properties", 3, mutualProps.size());
|
||||
assertTrue("All properties should be unique",
|
||||
mutualProps.stream().allMatch(PropertyWrapper::isUnique));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetMutualSelectionPropertiesWithDifferentValues() throws Exception {
|
||||
TestComponent comp1 = new TestComponent();
|
||||
TestComponent comp2 = new TestComponent();
|
||||
|
||||
// Set different values
|
||||
comp1.setTestProperty("value1");
|
||||
comp2.setTestProperty("value2");
|
||||
comp1.setNumericProperty(42);
|
||||
comp2.setNumericProperty(43);
|
||||
comp1.setName("name1");
|
||||
comp2.setName("name2");
|
||||
|
||||
List<PropertyWrapper> mutualProps = processor.getMutualSelectionProperties(
|
||||
Arrays.asList(comp1, comp2));
|
||||
|
||||
assertNotNull("Mutual properties should not be null", mutualProps);
|
||||
assertEquals("Should have 3 mutual properties", 3, mutualProps.size());
|
||||
|
||||
// Each property should not be unique since they have different values
|
||||
for (PropertyWrapper prop : mutualProps) {
|
||||
assertFalse("Property '" + prop.getName() + "' should not be unique",
|
||||
prop.isUnique());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testComponentPointsTouch() {
|
||||
TestComponent comp1 = new TestComponent();
|
||||
TestComponent comp2 = new TestComponent();
|
||||
|
||||
assertTrue("Components with same point should touch",
|
||||
ComponentProcessor.componentPointsTouch(comp1, comp2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHasStickyPoint() {
|
||||
TestComponent component = new TestComponent();
|
||||
assertTrue("Should have sticky point", ComponentProcessor.hasStickyPoint(component));
|
||||
}
|
||||
|
||||
private PropertyWrapper findPropertyByName(List<PropertyWrapper> properties, String name) {
|
||||
return properties.stream()
|
||||
.filter(p -> p.getName().equals(name))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,266 @@
|
||||
package org.diylc.presenter;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class DatasheetServiceTest {
|
||||
|
||||
private DatasheetService service;
|
||||
|
||||
@Mock
|
||||
private ClassLoader mockClassLoader;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
service = DatasheetService.getInstance();
|
||||
service.clearCache(); // Clear cache before each test
|
||||
Thread.currentThread().setContextClassLoader(mockClassLoader);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLoadDatasheet() throws Exception {
|
||||
// Create a mock datasheet content
|
||||
String datasheetContent =
|
||||
"1N4001,50V,1A,1.1V\n" +
|
||||
"1N4002,100V,1A,1.1V\n" +
|
||||
"1N4003,200V,1A,1.1V";
|
||||
|
||||
// Create a mock URL that returns our test content
|
||||
URL mockUrl = mock(URL.class);
|
||||
when(mockUrl.openStream()).thenReturn(
|
||||
new ByteArrayInputStream(datasheetContent.getBytes()));
|
||||
|
||||
// Setup the mock ClassLoader to return our mock URL
|
||||
when(mockClassLoader.getResource("TestComponent.datasheet"))
|
||||
.thenReturn(mockUrl);
|
||||
|
||||
// Test loading the datasheet
|
||||
List<String[]> result = service.loadDatasheet(TestComponent.class);
|
||||
|
||||
// Verify results
|
||||
assertNotNull("Datasheet should not be null", result);
|
||||
assertEquals("Should have 3 entries", 3, result.size());
|
||||
|
||||
// Verify first entry
|
||||
String[] firstEntry = result.get(0);
|
||||
assertEquals("1N4001", firstEntry[0]);
|
||||
assertEquals("50V", firstEntry[1]);
|
||||
assertEquals("1A", firstEntry[2]);
|
||||
assertEquals("1.1V", firstEntry[3]);
|
||||
|
||||
// Verify second entry
|
||||
String[] secondEntry = result.get(1);
|
||||
assertEquals("1N4002", secondEntry[0]);
|
||||
assertEquals("100V", secondEntry[1]);
|
||||
|
||||
// Verify third entry
|
||||
String[] thirdEntry = result.get(2);
|
||||
assertEquals("1N4003", thirdEntry[0]);
|
||||
assertEquals("200V", thirdEntry[1]);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLoadDatasheetFileNotFound() {
|
||||
// Setup the mock ClassLoader to return null (file not found)
|
||||
when(mockClassLoader.getResource("TestComponent.datasheet"))
|
||||
.thenReturn(null);
|
||||
|
||||
List<String[]> result = service.loadDatasheet(TestComponent.class);
|
||||
|
||||
assertNull("Result should be null when file is not found", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLookupExactMatch() throws Exception {
|
||||
// Create a mock datasheet content
|
||||
String datasheetContent =
|
||||
"TEST,KEY,10.0\n" +
|
||||
"TEST,KEY,20.0\n" +
|
||||
"TEST,OTHER,15.0\n" +
|
||||
"OTHER,KEY,10.0";
|
||||
|
||||
URL mockUrl = mock(URL.class);
|
||||
when(mockUrl.openStream()).thenReturn(
|
||||
new ByteArrayInputStream(datasheetContent.getBytes()));
|
||||
when(mockClassLoader.getResource("DatasheetServiceTest.datasheet"))
|
||||
.thenReturn(mockUrl);
|
||||
|
||||
// Create test data
|
||||
String[] result = service.lookup(
|
||||
DatasheetServiceTest.class, // Using test class itself as component class
|
||||
0.1, // 0.1% tolerance
|
||||
"TEST|KEY", // Key to look up
|
||||
10.0 // Value to match
|
||||
);
|
||||
|
||||
assertNotNull("Should find matching entry", result);
|
||||
assertEquals("TEST", result[0]);
|
||||
assertEquals("KEY", result[1]);
|
||||
assertEquals("10.0", result[2]);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLookupWithinTolerance() throws Exception {
|
||||
// Create a mock datasheet content
|
||||
String datasheetContent =
|
||||
"TEST,KEY,10.0\n" +
|
||||
"TEST,KEY,20.0\n" +
|
||||
"TEST,OTHER,15.0\n" +
|
||||
"OTHER,KEY,10.0";
|
||||
|
||||
URL mockUrl = mock(URL.class);
|
||||
when(mockUrl.openStream()).thenReturn(
|
||||
new ByteArrayInputStream(datasheetContent.getBytes()));
|
||||
when(mockClassLoader.getResource("DatasheetServiceTest.datasheet"))
|
||||
.thenReturn(mockUrl);
|
||||
|
||||
// Should match 10.0 with 5% tolerance when looking for 10.2
|
||||
String[] result = service.lookup(
|
||||
DatasheetServiceTest.class,
|
||||
5.0, // 5% tolerance
|
||||
"TEST|KEY",
|
||||
10.2 // Should match 10.0 within 5% tolerance
|
||||
);
|
||||
|
||||
assertNotNull("Should find matching entry within tolerance", result);
|
||||
assertEquals("10.0", result[2]);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLookupNoMatch() throws Exception {
|
||||
// Create a mock datasheet content
|
||||
String datasheetContent =
|
||||
"TEST,KEY,10.0\n" +
|
||||
"TEST,KEY,20.0\n" +
|
||||
"TEST,OTHER,15.0\n" +
|
||||
"OTHER,KEY,10.0";
|
||||
|
||||
URL mockUrl = mock(URL.class);
|
||||
when(mockUrl.openStream()).thenReturn(
|
||||
new ByteArrayInputStream(datasheetContent.getBytes()));
|
||||
when(mockClassLoader.getResource("DatasheetServiceTest.datasheet"))
|
||||
.thenReturn(mockUrl);
|
||||
|
||||
// Should not match when value is outside tolerance
|
||||
String[] result = service.lookup(
|
||||
DatasheetServiceTest.class,
|
||||
1.0, // 1% tolerance
|
||||
"TEST|KEY",
|
||||
15.0 // No value close enough to match
|
||||
);
|
||||
|
||||
assertNull("Should not find matching entry", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLookupNonexistentKey() throws Exception {
|
||||
// Create a mock datasheet content
|
||||
String datasheetContent =
|
||||
"TEST,KEY,10.0\n" +
|
||||
"TEST,KEY,20.0\n" +
|
||||
"TEST,OTHER,15.0\n" +
|
||||
"OTHER,KEY,10.0";
|
||||
|
||||
URL mockUrl = mock(URL.class);
|
||||
when(mockUrl.openStream()).thenReturn(
|
||||
new ByteArrayInputStream(datasheetContent.getBytes()));
|
||||
when(mockClassLoader.getResource("DatasheetServiceTest.datasheet"))
|
||||
.thenReturn(mockUrl);
|
||||
|
||||
String[] result = service.lookup(
|
||||
DatasheetServiceTest.class,
|
||||
0.1,
|
||||
"NONEXISTENT|KEY", // Key that doesn't exist in datasheet
|
||||
10.0
|
||||
);
|
||||
|
||||
assertNull("Should not find matching entry for nonexistent key", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLookupWithTolerance() throws Exception {
|
||||
// Create a mock datasheet content with resistor values
|
||||
String datasheetContent =
|
||||
"0805,1%,100,0.125W\n" +
|
||||
"0805,1%,220,0.125W\n" +
|
||||
"0805,1%,470,0.125W";
|
||||
|
||||
URL mockUrl = mock(URL.class);
|
||||
when(mockUrl.openStream()).thenReturn(
|
||||
new ByteArrayInputStream(datasheetContent.getBytes()));
|
||||
when(mockClassLoader.getResource("TestComponent.datasheet"))
|
||||
.thenReturn(mockUrl);
|
||||
|
||||
// Test lookup with 5% tolerance (should match 220 when looking for 225)
|
||||
String[] result = service.lookup(TestComponent.class, 5.0, "0805|1%", 225.0);
|
||||
|
||||
assertNotNull("Should find matching entry within tolerance", result);
|
||||
assertEquals("0805", result[0]);
|
||||
assertEquals("1%", result[1]);
|
||||
assertEquals("220", result[2]);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLookupOutsideTolerance() throws Exception {
|
||||
// Create a mock datasheet content
|
||||
String datasheetContent =
|
||||
"0805,1%,100,0.125W\n" +
|
||||
"0805,1%,220,0.125W\n" +
|
||||
"0805,1%,470,0.125W";
|
||||
|
||||
URL mockUrl = mock(URL.class);
|
||||
when(mockUrl.openStream()).thenReturn(
|
||||
new ByteArrayInputStream(datasheetContent.getBytes()));
|
||||
when(mockClassLoader.getResource("TestComponent.datasheet"))
|
||||
.thenReturn(mockUrl);
|
||||
|
||||
// Test lookup with value outside tolerance
|
||||
String[] result = service.lookup(TestComponent.class, 1.0, "0805|1%", 250.0);
|
||||
|
||||
assertNull("Should not find matching entry outside tolerance", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLookupMultipleValues() throws Exception {
|
||||
// Create a mock datasheet content with multiple value matches
|
||||
String datasheetContent =
|
||||
"TO220,NPN,50,5,0.7\n" + // Vce, Ic, Vbe
|
||||
"TO220,NPN,60,8,0.7\n" +
|
||||
"TO220,NPN,100,10,0.7";
|
||||
|
||||
URL mockUrl = mock(URL.class);
|
||||
when(mockUrl.openStream()).thenReturn(
|
||||
new ByteArrayInputStream(datasheetContent.getBytes()));
|
||||
when(mockClassLoader.getResource("TestComponent.datasheet"))
|
||||
.thenReturn(mockUrl);
|
||||
|
||||
// Test lookup matching multiple values within tolerance
|
||||
String[] result = service.lookup(TestComponent.class, 5.0, "TO220|NPN",
|
||||
98.0, 9.8, 0.71);
|
||||
|
||||
assertNotNull("Should find matching entry for multiple values", result);
|
||||
assertEquals("TO220", result[0]);
|
||||
assertEquals("NPN", result[1]);
|
||||
assertEquals("100", result[2]);
|
||||
assertEquals("10", result[3]);
|
||||
assertEquals("0.7", result[4]);
|
||||
}
|
||||
|
||||
// Test component class
|
||||
private static class TestComponent {
|
||||
// Empty class just for testing
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,173 @@
|
||||
/*
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
package org.diylc.testcomponents;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Point;
|
||||
import java.awt.geom.Point2D;
|
||||
|
||||
import org.diylc.components.AbstractComponent;
|
||||
import org.diylc.core.ComponentState;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
import org.diylc.core.IDrawingObserver;
|
||||
import org.diylc.core.Project;
|
||||
import org.diylc.core.VisibilityPolicy;
|
||||
import org.diylc.core.annotations.ComponentDescriptor;
|
||||
import org.diylc.core.annotations.EditableProperty;
|
||||
import org.diylc.core.measures.Capacitance;
|
||||
import org.diylc.core.measures.CapacitanceUnit;
|
||||
import org.diylc.core.measures.Resistance;
|
||||
import org.diylc.core.measures.ResistanceUnit;
|
||||
import org.diylc.core.measures.Size;
|
||||
import org.diylc.core.measures.SizeUnit;
|
||||
|
||||
@ComponentDescriptor(name = "Mock", author = "bancika", category = "Sample", instanceNamePrefix = "M",
|
||||
description = "test", zOrder = IDIYComponent.COMPONENT)
|
||||
public class MockDIYComponent extends AbstractComponent<Capacitance> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private String testField = "Hello World";
|
||||
private Capacitance c = new Capacitance(100d, CapacitanceUnit.uF);
|
||||
private Resistance r = new Resistance(123d, ResistanceUnit.K);
|
||||
private Size s = new Size(1d, SizeUnit.cm);
|
||||
private Color color = Color.green;
|
||||
private Point2D leftTopCorner = new Point(0, 0);
|
||||
private String name = "something";
|
||||
|
||||
public MockDIYComponent(String testField, Capacitance c, Resistance r, Size s, Color color, Point leftTopCorner) {
|
||||
super();
|
||||
this.testField = testField;
|
||||
this.c = c;
|
||||
this.r = r;
|
||||
this.s = s;
|
||||
this.color = color;
|
||||
this.leftTopCorner = leftTopCorner;
|
||||
}
|
||||
|
||||
public MockDIYComponent() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canControlPointOverlap(int index) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@EditableProperty
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getControlPointCount() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isControlPointSticky(int index) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VisibilityPolicy getControlPointVisibilityPolicy(int index) {
|
||||
return VisibilityPolicy.WHEN_SELECTED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Point2D getControlPoint(int index) {
|
||||
return leftTopCorner;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setControlPoint(Point2D point, int index) {
|
||||
leftTopCorner.setLocation(point);
|
||||
}
|
||||
|
||||
@EditableProperty(name = "Test Field")
|
||||
public String getTestField() {
|
||||
return testField;
|
||||
}
|
||||
|
||||
public void setTestField(String testField) {
|
||||
this.testField = testField;
|
||||
}
|
||||
|
||||
@EditableProperty(defaultable = true)
|
||||
public Capacitance getValue() {
|
||||
return c;
|
||||
}
|
||||
|
||||
public void setValue(Capacitance c) {
|
||||
this.c = c;
|
||||
}
|
||||
|
||||
@EditableProperty(defaultable = true)
|
||||
public Color getColor() {
|
||||
return color;
|
||||
}
|
||||
|
||||
public void setColor(Color color) {
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
@EditableProperty
|
||||
public Resistance getR() {
|
||||
return r;
|
||||
}
|
||||
|
||||
// Setter is commented out, ClassProcessor should ignore this property.
|
||||
// public void setR(Resistance r) {
|
||||
// this.r = r;
|
||||
// }
|
||||
|
||||
// No annotation, so this property should be ignored.
|
||||
public Size getS() {
|
||||
return s;
|
||||
}
|
||||
|
||||
public void setS(Size s) {
|
||||
this.s = s;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode, Project project,
|
||||
IDrawingObserver drawingObserver) {
|
||||
g2d.setColor(componentState.equals(ComponentState.SELECTED) ? color : color.darker());
|
||||
g2d.fillRect((int)leftTopCorner.getX(), (int)leftTopCorner.getY(), 200, 50);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawIcon(Graphics2D g2d, int width, int height) {
|
||||
g2d.drawString("X", 10, 10);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getControlPointNodeName(int index) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
TEST,KEY,10.0 mm
|
||||
TEST,KEY,20.0 mm
|
||||
TEST,OTHER,15.0 mm
|
||||
OTHER,KEY,10.0 mm
|
||||
Reference in New Issue
Block a user