Files
allwpilib/wpiunits/src/test/java/org/wpilib/units/UnitsTest.java
2025-11-07 23:09:21 -08:00

351 lines
11 KiB
Java

// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
package org.wpilib.units;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.wpilib.units.Units.Amps;
import static org.wpilib.units.Units.Celsius;
import static org.wpilib.units.Units.Centimeters;
import static org.wpilib.units.Units.Degrees;
import static org.wpilib.units.Units.Fahrenheit;
import static org.wpilib.units.Units.Feet;
import static org.wpilib.units.Units.FeetPerSecond;
import static org.wpilib.units.Units.Grams;
import static org.wpilib.units.Units.Gs;
import static org.wpilib.units.Units.Horsepower;
import static org.wpilib.units.Units.Inches;
import static org.wpilib.units.Units.Kelvin;
import static org.wpilib.units.Units.Kilo;
import static org.wpilib.units.Units.Kilograms;
import static org.wpilib.units.Units.Meters;
import static org.wpilib.units.Units.MetersPerSecond;
import static org.wpilib.units.Units.MetersPerSecondPerSecond;
import static org.wpilib.units.Units.Microseconds;
import static org.wpilib.units.Units.Milli;
import static org.wpilib.units.Units.Milliamps;
import static org.wpilib.units.Units.Millimeters;
import static org.wpilib.units.Units.Milliseconds;
import static org.wpilib.units.Units.Millivolts;
import static org.wpilib.units.Units.Milliwatts;
import static org.wpilib.units.Units.Minutes;
import static org.wpilib.units.Units.Ounces;
import static org.wpilib.units.Units.Percent;
import static org.wpilib.units.Units.Pounds;
import static org.wpilib.units.Units.Radians;
import static org.wpilib.units.Units.Revolutions;
import static org.wpilib.units.Units.Second;
import static org.wpilib.units.Units.Seconds;
import static org.wpilib.units.Units.Value;
import static org.wpilib.units.Units.Volts;
import static org.wpilib.units.Units.Watts;
import java.util.function.DoubleFunction;
import org.junit.jupiter.api.Test;
class UnitsTest {
// Be accurate to 0.01%
private static final double thresh = 1e-5;
void testBaseUnit(DoubleFunction<Measure<?>> baseUnit) {
assertEquals(0, baseUnit.apply(0).baseUnitMagnitude(), 0);
assertEquals(1, baseUnit.apply(1).baseUnitMagnitude(), 0);
assertEquals(-1, baseUnit.apply(-1).baseUnitMagnitude(), 0);
assertEquals(100, baseUnit.apply(100).baseUnitMagnitude(), 0);
assertEquals(8.281723, baseUnit.apply(8.281723).baseUnitMagnitude(), 0);
assertEquals(Float.MAX_VALUE, baseUnit.apply(Float.MAX_VALUE).baseUnitMagnitude(), 0);
assertEquals(Float.MIN_VALUE, baseUnit.apply(Float.MIN_VALUE).baseUnitMagnitude(), 0);
}
// Distances
@Test
void testMeters() {
testBaseUnit(Meters::of);
assertEquals("Meter", Meters.name());
assertEquals("m", Meters.symbol());
}
@Test
void testMillimeters() {
assertEquals(1000, Millimeters.convertFrom(1, Meters), thresh);
assertEquals(1, Meters.convertFrom(1000, Millimeters), thresh);
assertEquals("Millimeter", Millimeters.name());
assertEquals("mm", Millimeters.symbol());
}
@Test
void testCentimeters() {
assertEquals(100, Centimeters.convertFrom(1, Meters), thresh);
assertEquals(1, Meters.convertFrom(100, Centimeters), thresh);
assertEquals("Centimeter", Centimeters.name());
assertEquals("cm", Centimeters.symbol());
}
@Test
void testInches() {
assertEquals(1, Meters.convertFrom(39.3701, Inches), thresh);
assertEquals(39.3701, Inches.convertFrom(1, Meters), 1e-4);
assertEquals(1 / 25.4, Inches.convertFrom(1, Millimeters), 0); // should be exact
assertEquals(12, Inches.convertFrom(1, Feet), thresh);
assertEquals("Inch", Inches.name());
assertEquals("in", Inches.symbol());
}
@Test
void testFeet() {
assertEquals(3.28084, Feet.convertFrom(1, Meters), thresh);
assertEquals(1 / 12.0, Feet.convertFrom(1, Inches), thresh);
assertEquals("Foot", Feet.name());
assertEquals("ft", Feet.symbol());
}
// Velocities
@Test
void testMetersPerSecond() {
testBaseUnit(MetersPerSecond::of);
assertEquals("Meter per Second", MetersPerSecond.name());
assertEquals("m/s", MetersPerSecond.symbol());
}
@Test
void testFeetPerSecond() {
assertEquals(3.28084, FeetPerSecond.convertFrom(1, MetersPerSecond), thresh);
assertEquals(1 / 3.28084, MetersPerSecond.convertFrom(1, FeetPerSecond), thresh);
assertEquals("Foot per Second", FeetPerSecond.name());
assertEquals("ft/s", FeetPerSecond.symbol());
}
// Accelerations
@Test
void testMetersPerSecondPerSecond() {
testBaseUnit(MetersPerSecondPerSecond::of);
assertEquals("Meter per Second per Second", MetersPerSecondPerSecond.name());
assertEquals("m/s/s", MetersPerSecondPerSecond.symbol());
assertEquals(MetersPerSecond, MetersPerSecondPerSecond.getUnit());
assertEquals(Seconds, MetersPerSecondPerSecond.getPeriod());
}
@Test
void testGs() {
assertEquals(32.17405, Gs.of(1).in(FeetPerSecond.per(Second)), thresh);
assertEquals(9.80665, Gs.of(1).in(MetersPerSecondPerSecond), thresh);
assertEquals("G", Gs.name());
assertEquals("G", Gs.symbol());
assertEquals(MetersPerSecond, Gs.getUnit());
assertEquals(Seconds, Gs.getPeriod());
}
// Time
@Test
void testSeconds() {
testBaseUnit(Seconds::of);
assertEquals("Second", Seconds.name());
assertEquals("s", Seconds.symbol());
}
@Test
void testMillisecond() {
assertEquals(1000, Milliseconds.convertFrom(1, Seconds), thresh);
assertEquals("Millisecond", Milliseconds.name());
assertEquals("ms", Milliseconds.symbol());
}
@Test
void testMicrosecond() {
assertEquals(1e6, Microseconds.convertFrom(1, Second), 0);
assertEquals("Microsecond", Microseconds.name());
assertEquals("us", Microseconds.symbol());
}
@Test
void testMinutes() {
assertEquals(60, Seconds.convertFrom(1, Minutes), thresh);
assertEquals("Minute", Minutes.name());
assertEquals("min", Minutes.symbol());
}
// Mass
@Test
void testKilograms() {
testBaseUnit(Kilograms::of);
assertEquals("Kilogram", Kilograms.name());
assertEquals("Kg", Kilograms.symbol());
}
@Test
void testGrams() {
assertEquals(1000, Grams.convertFrom(1, Kilograms), thresh);
assertEquals("Gram", Grams.name());
assertEquals("g", Grams.symbol());
}
@Test
void testPounds() {
assertEquals(453.592, Grams.convertFrom(1, Pounds), thresh);
assertEquals("Pound", Pounds.name());
assertEquals("lb.", Pounds.symbol());
}
@Test
void testOunces() {
assertEquals(16, Ounces.convertFrom(1, Pounds), thresh);
assertEquals("Ounce", Ounces.name());
assertEquals("oz.", Ounces.symbol());
}
// Angle
@Test
void testRevolutions() {
assertEquals(1, Revolutions.convertFrom(2 * Math.PI, Radians), thresh);
assertEquals("Revolution", Revolutions.name());
assertEquals("R", Revolutions.symbol());
}
@Test
void testRadians() {
testBaseUnit(Radians::of);
assertEquals(2 * Math.PI, Radians.convertFrom(1, Revolutions), thresh);
assertEquals(2 * Math.PI, Radians.convertFrom(360, Degrees), thresh);
assertEquals("Radian", Radians.name());
assertEquals("rad", Radians.symbol());
}
@Test
void testDegrees() {
assertEquals(360, Degrees.convertFrom(1, Revolutions), thresh);
assertEquals(360, Degrees.convertFrom(2 * Math.PI, Radians), thresh);
assertEquals("Degree", Degrees.name());
assertEquals("°", Degrees.symbol());
}
// Unitless
@Test
void testValue() {
testBaseUnit(Value::of);
assertEquals("<?>", Value.name());
assertEquals("<?>", Value.symbol());
}
@Test
void testPercent() {
assertEquals(100, Percent.convertFrom(1, Value), thresh);
assertEquals("Percent", Percent.name());
assertEquals("%", Percent.symbol());
}
// Electric potential
@Test
void testVolts() {
testBaseUnit(Volts::of);
assertEquals("Volt", Volts.name());
assertEquals("V", Volts.symbol());
}
@Test
void testMillivolts() {
assertEquals(1000, Millivolts.convertFrom(1, Volts), thresh);
assertEquals("Millivolt", Millivolts.name());
assertEquals("mV", Millivolts.symbol());
}
// Electric current
@Test
void testAmps() {
testBaseUnit(Amps::of);
assertEquals("Amp", Amps.name());
assertEquals("A", Amps.symbol());
}
@Test
void testMilliamps() {
assertEquals(1000, Milliamps.convertFrom(1, Amps), thresh);
assertEquals("Milliamp", Milliamps.name());
assertEquals("mA", Milliamps.symbol());
}
// Power
@Test
void testWatts() {
testBaseUnit(Watts::of);
assertEquals("Watt", Watts.name());
assertEquals("W", Watts.symbol());
}
@Test
void testMilliwatts() {
assertEquals(1000, Milliwatts.convertFrom(1, Watts), thresh);
assertEquals("Milliwatt", Milliwatts.name());
assertEquals("mW", Milliwatts.symbol());
}
@Test
void testHorsepower() {
assertEquals(745.7, Watts.convertFrom(1, Horsepower), thresh);
assertEquals("Horsepower", Horsepower.name());
assertEquals("HP", Horsepower.symbol());
}
// Temperature
@Test
void testKelvin() {
testBaseUnit(Kelvin::of);
assertEquals("Kelvin", Kelvin.name());
assertEquals("K", Kelvin.symbol()); // note: there's no degree symbol for Kelvin!
}
@Test
void testCelsius() {
assertEquals(0, Celsius.of(-273.15).in(Kelvin), thresh);
assertEquals(273.15, Celsius.of(0).in(Kelvin), thresh);
assertEquals(0, Kelvin.of(273.15).in(Celsius), thresh);
assertTrue(Celsius.of(0).isEquivalent(Kelvin.of(273.15)));
assertTrue(Celsius.of(-273.15).isEquivalent(Kelvin.of(0)));
assertEquals("Celsius", Celsius.name());
assertEquals("°C", Celsius.symbol());
}
@Test
void testFahrenheit() {
assertEquals(0, Fahrenheit.of(32).in(Celsius), thresh);
assertEquals(100, Fahrenheit.of(212).in(Celsius), thresh);
assertEquals(-459.67, Kelvin.of(0).in(Fahrenheit), thresh);
assertEquals(273.15, Fahrenheit.of(32).in(Kelvin), thresh);
assertEquals(32, Kelvin.of(273.15).in(Fahrenheit), thresh);
assertTrue(Fahrenheit.of(32).isEquivalent(Celsius.of(0)));
assertTrue(Fahrenheit.of(212).isEquivalent(Celsius.of(100)));
assertEquals("Fahrenheit", Fahrenheit.name());
assertEquals("°F", Fahrenheit.symbol());
}
// Helpers
@Test
void testKilo() {
ExampleUnit unit = new ExampleUnit(1);
ExampleUnit kiloUnit = Kilo(unit);
assertEquals(1e3, unit.convertFrom(1, kiloUnit), 0);
assertEquals(1e-3, kiloUnit.convertFrom(1, unit), 0);
}
@Test
void testMilli() {
ExampleUnit unit = new ExampleUnit(1);
ExampleUnit milliUnit = Milli(unit);
assertEquals(1e-3, unit.convertFrom(1, milliUnit), 0);
assertEquals(1e3, milliUnit.convertFrom(1, unit), 0);
}
}