mirror of
https://github.com/bancika/diy-layout-creator
synced 2026-11-13 02:32:09 +10:00
Added 'Value Notation' to the Config menu
This commit is contained in:
@@ -90,6 +90,7 @@ public interface IPlugInPort extends ISelectionProcessor, IMouseProcessor, IKeyP
|
||||
public static final String FONT_SCALE_FACTOR_KEY = "fontScaleFactor";
|
||||
public static final String SHOW_RESIZE_DIMENSIONS_TOOLTIP_KEY = "showResizeDimensionsTooltip";
|
||||
public static final String AUTO_UNIT_CONVERSION_KEY = "autoUnitConversion";
|
||||
public static final String VALUE_NOTATION_KEY = "valueNotation";
|
||||
|
||||
|
||||
public static final String RULER_IN_SUBDIVISION_2 = "base of 2";
|
||||
@@ -101,6 +102,10 @@ public interface IPlugInPort extends ISelectionProcessor, IMouseProcessor, IKeyP
|
||||
public static final String SNAP_TO_COMPONENTS = "Components";
|
||||
public static final String SNAP_TO_DEFAULT = SNAP_TO_GRID;
|
||||
|
||||
public static final String VALUE_NOTATION_DECIMAL = "Decimal (4.7K, 0.22uF)";
|
||||
public static final String VALUE_NOTATION_RKM = "RKM (4K7, 0u22)";
|
||||
public static final String VALUE_NOTATION_DEFAULT = VALUE_NOTATION_DECIMAL;
|
||||
|
||||
public static final String SHOW_NODE_NAME_TOOLTIPS_KEY = "showNodeNameTooltips";
|
||||
|
||||
public static final String LOCKED_ALPHA = "lockedAlpha";
|
||||
|
||||
@@ -41,14 +41,16 @@ public class Capacitance extends AbstractMeasure<CapacitanceUnit> {
|
||||
}
|
||||
|
||||
public static Capacitance parseCapacitance(String value) {
|
||||
value = value.replace("*", "");
|
||||
for (CapacitanceUnit unit : CapacitanceUnit.values()) {
|
||||
if (value.toLowerCase().endsWith(unit.toString().toLowerCase())) {
|
||||
value = value.substring(0, value.length() - unit.toString().length()).trim();
|
||||
return new Capacitance(parse(value), unit);
|
||||
}
|
||||
ValueNotation.ParsedMeasure<CapacitanceUnit> parsed;
|
||||
try {
|
||||
parsed = ValueNotation.parse(value, CapacitanceUnit::fromSymbol);
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new IllegalArgumentException("Could not parse capacitance: " + value, e);
|
||||
}
|
||||
throw new IllegalArgumentException("Could not parse capacitance: " + value);
|
||||
if (parsed.unit() == null) {
|
||||
throw new IllegalArgumentException("Could not parse capacitance: " + value);
|
||||
}
|
||||
return new Capacitance(parsed.value(), parsed.unit());
|
||||
}
|
||||
|
||||
public Double getNormalizedValue() {
|
||||
@@ -56,4 +58,12 @@ public class Capacitance extends AbstractMeasure<CapacitanceUnit> {
|
||||
return null;
|
||||
return value * unit.getFactor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (ValueNotation.getCurrent() == ValueNotation.RKM && value != null && unit != null) {
|
||||
return ValueNotation.formatRkm(value, unit.getRkmSymbol());
|
||||
}
|
||||
return super.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,14 +23,16 @@ package org.diylc.core.measures;
|
||||
|
||||
public enum CapacitanceUnit implements Unit {
|
||||
|
||||
pF(1e-6, "pF"), nF(1e-3, "nF"), uF(1, "uF"), mF(1e3, "mF"), F(1e6, "F");
|
||||
pF(1e-6, "pF", "p"), nF(1e-3, "nF", "n"), uF(1, "uF", "u"), mF(1e3, "mF", "m"), F(1e6, "F", "F");
|
||||
|
||||
double factor;
|
||||
String display;
|
||||
String rkmSymbol;
|
||||
|
||||
private CapacitanceUnit(double factor, String display) {
|
||||
private CapacitanceUnit(double factor, String display, String rkmSymbol) {
|
||||
this.factor = factor;
|
||||
this.display = display;
|
||||
this.rkmSymbol = rkmSymbol;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -38,8 +40,49 @@ public enum CapacitanceUnit implements Unit {
|
||||
return factor;
|
||||
}
|
||||
|
||||
public String getRkmSymbol() {
|
||||
return rkmSymbol;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return display;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the unit written after a capacitance value, e.g. "nF", "n", "u", "\u00B5F" or "F".
|
||||
* Case does not matter when the trailing "F" is present, which is how values have always been
|
||||
* parsed. Without it, "M" is rejected so that it is never mistaken for mega.
|
||||
*
|
||||
* @param symbol unit text with no surrounding whitespace
|
||||
* @return the unit, or null when the text is not a capacitance unit
|
||||
*/
|
||||
public static CapacitanceUnit fromSymbol(String symbol) {
|
||||
if (symbol.equalsIgnoreCase("F")) {
|
||||
return F;
|
||||
}
|
||||
String prefix = symbol;
|
||||
if (symbol.length() == 2 && (symbol.endsWith("F") || symbol.endsWith("f"))) {
|
||||
prefix = symbol.substring(0, 1).toLowerCase();
|
||||
} else if (symbol.equals("M")) {
|
||||
return null;
|
||||
}
|
||||
switch (prefix) {
|
||||
case "p":
|
||||
case "P":
|
||||
return pF;
|
||||
case "n":
|
||||
case "N":
|
||||
return nF;
|
||||
case "u":
|
||||
case "U":
|
||||
case "\u00B5":
|
||||
case "\u03BC":
|
||||
return uF;
|
||||
case "m":
|
||||
return mF;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,14 +109,16 @@ public class Resistance extends AbstractMeasure<ResistanceUnit> {
|
||||
}
|
||||
|
||||
public static Resistance parseResistance(String value) {
|
||||
value = value.replace("*", "").replace("R", "\u2126");
|
||||
for (ResistanceUnit unit : ResistanceUnit.values()) {
|
||||
if (value.toLowerCase().endsWith(unit.toString().toLowerCase())) {
|
||||
value = value.substring(0, value.length() - unit.toString().length()).trim();
|
||||
return new Resistance(parse(value), unit);
|
||||
}
|
||||
ValueNotation.ParsedMeasure<ResistanceUnit> parsed;
|
||||
try {
|
||||
parsed = ValueNotation.parse(value, ResistanceUnit::fromSymbol);
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new IllegalArgumentException("Could not parse resistance: " + value, e);
|
||||
}
|
||||
throw new IllegalArgumentException("Could not parse resistance: " + value);
|
||||
if (parsed.unit() == null) {
|
||||
throw new IllegalArgumentException("Could not parse resistance: " + value);
|
||||
}
|
||||
return new Resistance(parsed.value(), parsed.unit());
|
||||
}
|
||||
|
||||
public Double getNormalizedValue() {
|
||||
@@ -124,4 +126,12 @@ public class Resistance extends AbstractMeasure<ResistanceUnit> {
|
||||
return null;
|
||||
return value * unit.getFactor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (ValueNotation.getCurrent() == ValueNotation.RKM && value != null && unit != null) {
|
||||
return ValueNotation.formatRkm(value, unit.getRkmSymbol());
|
||||
}
|
||||
return super.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,14 +23,16 @@ package org.diylc.core.measures;
|
||||
|
||||
public enum ResistanceUnit implements Unit {
|
||||
|
||||
R(1, "\u03A9"), K(1e3, "K"), M(1e6, "M");
|
||||
R(1, "\u03A9", "R"), K(1e3, "K", "K"), M(1e6, "M", "M");
|
||||
|
||||
double factor;
|
||||
String display;
|
||||
String rkmSymbol;
|
||||
|
||||
private ResistanceUnit(double factor, String display) {
|
||||
private ResistanceUnit(double factor, String display, String rkmSymbol) {
|
||||
this.factor = factor;
|
||||
this.display = display;
|
||||
this.rkmSymbol = rkmSymbol;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -39,8 +41,45 @@ public enum ResistanceUnit implements Unit {
|
||||
|
||||
}
|
||||
|
||||
public String getRkmSymbol() {
|
||||
return rkmSymbol;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return display;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the unit written after a resistance value, e.g. "K", "kohm", "R", "\u03A9" or "Meg".
|
||||
* A lower-case "m" means mega, because there is no milliohm unit and parts lists commonly write
|
||||
* "1m" for one megohm.
|
||||
*
|
||||
* @param symbol unit text with no surrounding whitespace
|
||||
* @return the unit, or null when the text is not a resistance unit
|
||||
*/
|
||||
public static ResistanceUnit fromSymbol(String symbol) {
|
||||
String prefix = symbol;
|
||||
String lower = symbol.toLowerCase();
|
||||
for (String ohm : new String[] {"ohms", "ohm", "\u03A9", "\u2126"}) {
|
||||
if (lower.endsWith(ohm.toLowerCase())) {
|
||||
prefix = symbol.substring(0, symbol.length() - ohm.length());
|
||||
if (prefix.isEmpty()) {
|
||||
return R;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
switch (prefix.toLowerCase()) {
|
||||
case "r":
|
||||
return R;
|
||||
case "k":
|
||||
return K;
|
||||
case "m":
|
||||
case "meg":
|
||||
return M;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
|
||||
DIY Layout Creator (DIYLC).
|
||||
Copyright (c) 2009-2025 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.core.measures;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.DecimalFormatSymbols;
|
||||
import java.util.Locale;
|
||||
import java.util.function.Function;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Notation used to write resistance and capacitance values: plain decimal ("4.7K", "0.22uF") or
|
||||
* RKM as defined by IEC 60062, where the unit symbol takes the place of the decimal point ("4K7",
|
||||
* "0u22"). Parsing accepts both regardless of the selected notation.
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*/
|
||||
public enum ValueNotation {
|
||||
|
||||
DECIMAL, RKM;
|
||||
|
||||
private static final DecimalFormat RKM_FORMAT =
|
||||
new DecimalFormat("0.####", DecimalFormatSymbols.getInstance(Locale.US));
|
||||
|
||||
private static final Pattern RKM_PATTERN = Pattern.compile("^(-?)(\\d*)([^\\d.\\-]+)(\\d+)([^\\d.]*)$");
|
||||
|
||||
// read on every repaint through toString(), so it is kept here rather than looked up in the
|
||||
// configuration
|
||||
private static volatile ValueNotation current = DECIMAL;
|
||||
|
||||
public static ValueNotation getCurrent() {
|
||||
return current;
|
||||
}
|
||||
|
||||
public static void setCurrent(ValueNotation notation) {
|
||||
current = notation == null ? DECIMAL : notation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a value in RKM notation, e.g. 4.7 with "K" becomes "4K7" and 100 with "R" becomes
|
||||
* "100R". The value is kept in the unit it is stored in and never renormalized.
|
||||
*
|
||||
* @param value value expressed in the unit
|
||||
* @param rkmSymbol symbol that stands in for the decimal point
|
||||
* @return RKM code
|
||||
*/
|
||||
public static String formatRkm(double value, String rkmSymbol) {
|
||||
String text;
|
||||
synchronized (RKM_FORMAT) {
|
||||
text = RKM_FORMAT.format(value);
|
||||
}
|
||||
int dot = text.indexOf('.');
|
||||
if (dot < 0) {
|
||||
return text + rkmSymbol;
|
||||
}
|
||||
return text.substring(0, dot) + rkmSymbol + text.substring(dot + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a value written either in decimal notation with an optional unit ("4.7", "4.7k",
|
||||
* "0.22 uF") or in RKM notation ("4K7", "R22", "2n2F").
|
||||
*
|
||||
* @param text text to parse
|
||||
* @param unitResolver maps the unit text to a unit, returning null when it is not recognized
|
||||
* @return parsed value; its unit is null when the text carries no unit
|
||||
* @throws IllegalArgumentException when the text cannot be parsed
|
||||
*/
|
||||
public static <U extends Unit> ParsedMeasure<U> parse(String text,
|
||||
Function<String, U> unitResolver) {
|
||||
if (text == null) {
|
||||
throw new IllegalArgumentException("Nothing to parse");
|
||||
}
|
||||
String value = text.replace("*", "").replace(",", ".").replaceAll("\\s", "");
|
||||
if (value.isEmpty()) {
|
||||
throw new IllegalArgumentException("Nothing to parse");
|
||||
}
|
||||
|
||||
int unitStart = value.length();
|
||||
while (unitStart > 0 && !Character.isDigit(value.charAt(unitStart - 1))
|
||||
&& value.charAt(unitStart - 1) != '.') {
|
||||
unitStart--;
|
||||
}
|
||||
String number = value.substring(0, unitStart);
|
||||
String unitText = value.substring(unitStart);
|
||||
U unit = unitText.isEmpty() ? null : unitResolver.apply(unitText);
|
||||
if (unitText.isEmpty() || unit != null) {
|
||||
try {
|
||||
return new ParsedMeasure<U>(Double.parseDouble(number), unit);
|
||||
} catch (NumberFormatException e) {
|
||||
// not a decimal number, try RKM below
|
||||
}
|
||||
}
|
||||
|
||||
Matcher matcher = RKM_PATTERN.matcher(value);
|
||||
if (matcher.matches()) {
|
||||
unit = unitResolver.apply(matcher.group(3) + matcher.group(5));
|
||||
if (unit != null) {
|
||||
String integerPart = matcher.group(2).isEmpty() ? "0" : matcher.group(2);
|
||||
double parsed = Double.parseDouble(integerPart + "." + matcher.group(4));
|
||||
return new ParsedMeasure<U>(matcher.group(1).isEmpty() ? parsed : -parsed, unit);
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("Could not parse value: " + text);
|
||||
}
|
||||
|
||||
public record ParsedMeasure<U extends Unit>(double value, U unit) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
|
||||
DIY Layout Creator (DIYLC).
|
||||
Copyright (c) 2009-2025 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 org.diylc.appframework.miscutils.IConfigurationManager;
|
||||
|
||||
import org.diylc.common.IPlugInPort;
|
||||
import org.diylc.core.measures.ValueNotation;
|
||||
|
||||
/**
|
||||
* Keeps {@link ValueNotation#getCurrent()} in sync with the value notation the user picked in the
|
||||
* configuration, and redraws the project when it changes. The notation is global, so only the
|
||||
* main window binds it; secondary presenters (previews, thumbnails, batch conversion, regression
|
||||
* runs) run on in-memory configurations and must not reset it.
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*/
|
||||
public class ValueNotationBinder {
|
||||
|
||||
public static void bind(IConfigurationManager<?> configManager, Runnable refresh) {
|
||||
apply(configManager.readString(IPlugInPort.VALUE_NOTATION_KEY,
|
||||
IPlugInPort.VALUE_NOTATION_DEFAULT));
|
||||
configManager.addConfigListener(IPlugInPort.VALUE_NOTATION_KEY, (key, value) -> {
|
||||
apply(value == null ? null : value.toString());
|
||||
// cached component images still carry the labels drawn in the previous notation
|
||||
DrawingCache.Instance.clear();
|
||||
refresh.run();
|
||||
});
|
||||
}
|
||||
|
||||
static void apply(String configValue) {
|
||||
ValueNotation.setCurrent(IPlugInPort.VALUE_NOTATION_RKM.equalsIgnoreCase(configValue)
|
||||
? ValueNotation.RKM : ValueNotation.DECIMAL);
|
||||
}
|
||||
}
|
||||
@@ -629,6 +629,10 @@
|
||||
<releaseDate>2026-11-07 00:00:00.000 CET</releaseDate>
|
||||
<name></name>
|
||||
<changes>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Added 'Value Notation' to the Config menu to show resistance and capacitance values in RKM notation, e.g. 4K7, 0R22, 2n2 or 0u22, instead of decimal; values can be typed in either notation, and typing the unit together with the value, e.g. 4K7 or 2.2nF, sets the unit at the same time</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>BUG_FIX</changeType>
|
||||
<description>Rotated labels in pasted components and building blocks were drawn in the wrong place and at the wrong angle while following the mouse, until the components were placed</description>
|
||||
|
||||
@@ -0,0 +1,203 @@
|
||||
/*
|
||||
|
||||
DIY Layout Creator (DIYLC).
|
||||
Copyright (c) 2009-2025 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.core.measures;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
|
||||
public class ValueNotationTest {
|
||||
|
||||
private static final double DELTA = 1e-9;
|
||||
|
||||
@After
|
||||
public void resetNotation() {
|
||||
ValueNotation.setCurrent(ValueNotation.DECIMAL);
|
||||
}
|
||||
|
||||
// --- formatting ---
|
||||
|
||||
@Test
|
||||
public void decimalResistanceIsUnchanged() {
|
||||
assertEquals("4.7\u03A9", new Resistance(4.7, ResistanceUnit.R).toString());
|
||||
assertEquals("0.22\u03A9", new Resistance(0.22, ResistanceUnit.R).toString());
|
||||
assertEquals("4.7K", new Resistance(4.7, ResistanceUnit.K).toString());
|
||||
assertEquals("1M", new Resistance(1d, ResistanceUnit.M).toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void decimalCapacitanceIsUnchanged() {
|
||||
assertEquals("0.22uF", new Capacitance(0.22, CapacitanceUnit.uF).toString());
|
||||
assertEquals("100nF", new Capacitance(100d, CapacitanceUnit.nF).toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void rkmResistance() {
|
||||
ValueNotation.setCurrent(ValueNotation.RKM);
|
||||
assertEquals("4R7", new Resistance(4.7, ResistanceUnit.R).toString());
|
||||
assertEquals("0R22", new Resistance(0.22, ResistanceUnit.R).toString());
|
||||
assertEquals("100R", new Resistance(100d, ResistanceUnit.R).toString());
|
||||
assertEquals("4K7", new Resistance(4.7, ResistanceUnit.K).toString());
|
||||
assertEquals("47K", new Resistance(47d, ResistanceUnit.K).toString());
|
||||
assertEquals("1M", new Resistance(1d, ResistanceUnit.M).toString());
|
||||
assertEquals("4700R", new Resistance(4700d, ResistanceUnit.R).toString());
|
||||
assertEquals("0R", new Resistance(0d, ResistanceUnit.R).toString());
|
||||
assertEquals("4K7501", new Resistance(4.75012, ResistanceUnit.K).toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void rkmCapacitance() {
|
||||
ValueNotation.setCurrent(ValueNotation.RKM);
|
||||
assertEquals("0u22", new Capacitance(0.22, CapacitanceUnit.uF).toString());
|
||||
assertEquals("2n2", new Capacitance(2.2, CapacitanceUnit.nF).toString());
|
||||
assertEquals("100n", new Capacitance(100d, CapacitanceUnit.nF).toString());
|
||||
assertEquals("4p7", new Capacitance(4.7, CapacitanceUnit.pF).toString());
|
||||
assertEquals("1000u", new Capacitance(1000d, CapacitanceUnit.uF).toString());
|
||||
}
|
||||
|
||||
// --- parsing ---
|
||||
|
||||
@Test
|
||||
public void parsesDecimalResistance() {
|
||||
assertResistance(4.7, ResistanceUnit.K, "4.7K");
|
||||
assertResistance(4.7, ResistanceUnit.K, "4.7k");
|
||||
assertResistance(4.7, ResistanceUnit.K, "4.7 K");
|
||||
assertResistance(4.7, ResistanceUnit.K, "4,7K");
|
||||
assertResistance(4.7, ResistanceUnit.K, "4.7kohm");
|
||||
assertResistance(4.7, ResistanceUnit.R, "4.7ohm");
|
||||
assertResistance(4.7, ResistanceUnit.R, "4.7 ohms");
|
||||
assertResistance(4.7, ResistanceUnit.R, "4.7\u03A9");
|
||||
assertResistance(4.7, ResistanceUnit.R, "4.7\u2126");
|
||||
assertResistance(4.7, ResistanceUnit.K, "4.7K\u03A9");
|
||||
assertResistance(1, ResistanceUnit.M, "1M");
|
||||
assertResistance(1, ResistanceUnit.M, "1m");
|
||||
assertResistance(2.2, ResistanceUnit.M, "2.2Meg");
|
||||
assertResistance(100, ResistanceUnit.R, "100R");
|
||||
assertResistance(100, ResistanceUnit.R, "100r");
|
||||
assertResistance(0.5, ResistanceUnit.K, ".5K");
|
||||
assertResistance(10, ResistanceUnit.K, "10K*");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parsesRkmResistance() {
|
||||
assertResistance(4.7, ResistanceUnit.R, "4R7");
|
||||
assertResistance(0.22, ResistanceUnit.R, "0R22");
|
||||
assertResistance(0.22, ResistanceUnit.R, "R22");
|
||||
assertResistance(4.7, ResistanceUnit.K, "4K7");
|
||||
assertResistance(4.7, ResistanceUnit.K, "4k7");
|
||||
assertResistance(4.75, ResistanceUnit.K, "4K75");
|
||||
assertResistance(2.2, ResistanceUnit.M, "2M2");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parsesDecimalCapacitance() {
|
||||
assertCapacitance(0.22, CapacitanceUnit.uF, "0.22uF");
|
||||
assertCapacitance(0.22, CapacitanceUnit.uF, "0.22UF");
|
||||
assertCapacitance(0.22, CapacitanceUnit.uF, "0.22u");
|
||||
assertCapacitance(220, CapacitanceUnit.nF, "220 nF");
|
||||
assertCapacitance(220, CapacitanceUnit.nF, "220n");
|
||||
assertCapacitance(47, CapacitanceUnit.pF, "47pf");
|
||||
assertCapacitance(4.7, CapacitanceUnit.uF, "4.7\u00B5F");
|
||||
assertCapacitance(1, CapacitanceUnit.F, "1F");
|
||||
assertCapacitance(1, CapacitanceUnit.mF, "1mF");
|
||||
assertCapacitance(1, CapacitanceUnit.mF, "1MF");
|
||||
assertCapacitance(1, CapacitanceUnit.mF, "1m");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parsesRkmCapacitance() {
|
||||
assertCapacitance(0.22, CapacitanceUnit.uF, "0u22");
|
||||
assertCapacitance(0.22, CapacitanceUnit.uF, "u22");
|
||||
assertCapacitance(2.2, CapacitanceUnit.nF, "2n2");
|
||||
assertCapacitance(2.2, CapacitanceUnit.nF, "2n2F");
|
||||
assertCapacitance(4.7, CapacitanceUnit.uF, "4u7");
|
||||
assertCapacitance(4.7, CapacitanceUnit.uF, "4\u00B57");
|
||||
assertCapacitance(4.7, CapacitanceUnit.uF, "4\u03BC7");
|
||||
assertCapacitance(4.7, CapacitanceUnit.pF, "4p7");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bareNumberHasNoUnit() {
|
||||
ValueNotation.ParsedMeasure<ResistanceUnit> parsed =
|
||||
ValueNotation.parse("4.7", ResistanceUnit::fromSymbol);
|
||||
assertEquals(4.7, parsed.value(), DELTA);
|
||||
assertNull(parsed.unit());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void rejectsInvalidText() {
|
||||
assertRejected("4u7", ResistanceUnit.class);
|
||||
assertRejected("4K7K", ResistanceUnit.class);
|
||||
assertRejected("K", ResistanceUnit.class);
|
||||
assertRejected("", ResistanceUnit.class);
|
||||
assertRejected("100", ResistanceUnit.class);
|
||||
assertRejected("4R7", CapacitanceUnit.class);
|
||||
assertRejected("1M", CapacitanceUnit.class);
|
||||
assertRejected("4M7", CapacitanceUnit.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void roundTripsInBothNotations() {
|
||||
double[] values = {0.22, 1, 4.7, 47, 100, 4700, 0.0047};
|
||||
for (ValueNotation notation : ValueNotation.values()) {
|
||||
ValueNotation.setCurrent(notation);
|
||||
for (double value : values) {
|
||||
for (ResistanceUnit unit : ResistanceUnit.values()) {
|
||||
Resistance resistance = new Resistance(value, unit);
|
||||
assertEquals(resistance, Resistance.parseResistance(resistance.toString()));
|
||||
}
|
||||
for (CapacitanceUnit unit : CapacitanceUnit.values()) {
|
||||
Capacitance capacitance = new Capacitance(value, unit);
|
||||
assertEquals(capacitance, Capacitance.parseCapacitance(capacitance.toString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void assertResistance(double value, ResistanceUnit unit, String text) {
|
||||
Resistance parsed = Resistance.parseResistance(text);
|
||||
assertEquals(text, value, parsed.getValue(), DELTA);
|
||||
assertEquals(text, unit, parsed.getUnit());
|
||||
}
|
||||
|
||||
private static void assertCapacitance(double value, CapacitanceUnit unit, String text) {
|
||||
Capacitance parsed = Capacitance.parseCapacitance(text);
|
||||
assertEquals(text, value, parsed.getValue(), DELTA);
|
||||
assertEquals(text, unit, parsed.getUnit());
|
||||
}
|
||||
|
||||
private static void assertRejected(String text, Class<?> unitType) {
|
||||
try {
|
||||
if (unitType == ResistanceUnit.class) {
|
||||
Resistance.parseResistance(text);
|
||||
} else {
|
||||
Capacitance.parseCapacitance(text);
|
||||
}
|
||||
fail("Expected " + text + " to be rejected");
|
||||
} catch (IllegalArgumentException e) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user