262 lines
9.5 KiB
Java
262 lines
9.5 KiB
Java
package jmri.implementation;
|
|
|
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
|
|
|
import static org.junit.jupiter.api.Assumptions.assumeTrue;
|
|
|
|
import java.beans.PropertyChangeListener;
|
|
|
|
import jmri.JmriException;
|
|
import jmri.Sensor;
|
|
import jmri.util.JUnitUtil;
|
|
|
|
import org.junit.jupiter.api.*;
|
|
|
|
|
|
/**
|
|
* Abstract Base Class for Sensor tests in specific jmrix packages. This is not
|
|
* itself a test class, e.g. should not be added to a suite. Instead, this forms
|
|
* the base for test classes, including providing some common tests.
|
|
*
|
|
* @author Bob Jacobsen 2016 from AbstractLightTestBase (which was called AbstractLightTest at the time)
|
|
* @author Paul Bender Copyright (C) 2018
|
|
*/
|
|
public abstract class AbstractSensorTestBase {
|
|
|
|
// implementing classes must provide these these methods
|
|
|
|
// return number of listeners registered with the TrafficController
|
|
abstract public int numListeners();
|
|
|
|
abstract public void checkActiveMsgSent();
|
|
|
|
abstract public void checkInactiveMsgSent();
|
|
|
|
abstract public void checkStatusRequestMsgSent();
|
|
|
|
// implementing classes must provide this abstract member:
|
|
abstract public void setUp(); // load t with actual object; create scaffolds as needed
|
|
|
|
protected AbstractSensor t = null; // holds object under test; set by setUp()
|
|
|
|
protected boolean listenerResult = false;
|
|
|
|
protected class Listen implements PropertyChangeListener {
|
|
@Override
|
|
public void propertyChange(java.beans.PropertyChangeEvent e) {
|
|
listenerResult = true;
|
|
}
|
|
}
|
|
|
|
// start of common tests
|
|
// test creation - real work is in the setup() routine
|
|
@Test
|
|
public void testCreate() {
|
|
// initial state when created must be UNKNOWN
|
|
assertEquals( Sensor.UNKNOWN, t.getState(), "initial state 1 unknown");
|
|
assertEquals( "Unknown", t.describeState(t.getState()), "initial state 2");
|
|
}
|
|
|
|
@Test
|
|
public void testAddListener() throws JmriException {
|
|
t.addPropertyChangeListener(new Listen());
|
|
listenerResult = false;
|
|
t.setUserName("user id");
|
|
assertTrue( listenerResult, "listener invoked by setUserName");
|
|
listenerResult = false;
|
|
t.setState(Sensor.ACTIVE);
|
|
assertTrue( listenerResult, "listener invoked by setState");
|
|
}
|
|
|
|
@Test
|
|
public void testRemoveListener() {
|
|
Listen ln = new Listen();
|
|
t.addPropertyChangeListener(ln);
|
|
t.removePropertyChangeListener(ln);
|
|
listenerResult = false;
|
|
t.setUserName("user id");
|
|
assertFalse( listenerResult,
|
|
"listener should not have heard message after removeListener");
|
|
}
|
|
|
|
@Test
|
|
public void testDispose() throws JmriException {
|
|
t.setState(Sensor.ACTIVE); // in case registration with TrafficController is deferred to after first use
|
|
t.dispose();
|
|
assertEquals( 0, numListeners(), "controller listeners remaining");
|
|
}
|
|
|
|
@Test
|
|
public void testRemoveListenerOnDispose() {
|
|
assertEquals( 0, t.getNumPropertyChangeListeners(), "starts 0 listeners");
|
|
t.addPropertyChangeListener(new Listen());
|
|
assertEquals( 1, t.getNumPropertyChangeListeners(), "controller listener added");
|
|
t.dispose();
|
|
assertTrue( t.getNumPropertyChangeListeners() < 1, "controller listeners remaining < 1");
|
|
}
|
|
|
|
@Test
|
|
public void testCommandInactive() throws JmriException {
|
|
t.setState(Sensor.INACTIVE);
|
|
// check
|
|
assertEquals( Sensor.INACTIVE, t.getState(), "state 1");
|
|
assertEquals( "Inactive", t.describeState(t.getState()), "state 2");
|
|
}
|
|
|
|
@Test
|
|
public void testCommandActive() throws JmriException {
|
|
t.setState(Sensor.ACTIVE);
|
|
// check
|
|
assertEquals( Sensor.ACTIVE, t.getState(), "state 1");
|
|
assertEquals( "Active", t.describeState(t.getState()), "state 2");
|
|
}
|
|
|
|
@Test
|
|
public void testCommandSentActive() throws JmriException {
|
|
t.setState(Sensor.ACTIVE);
|
|
assertEquals( Sensor.ACTIVE, t.getState(), "Sensor goes active");
|
|
checkActiveMsgSent();
|
|
}
|
|
|
|
@Test
|
|
public void testCommandSentInactive() throws JmriException {
|
|
t.setState(Sensor.INACTIVE);
|
|
assertEquals( Sensor.INACTIVE, t.getState(), "sensor goes inactive");
|
|
checkInactiveMsgSent();
|
|
}
|
|
|
|
@Test
|
|
public void testInvertAfterInactive() throws JmriException {
|
|
assumeTrue(t.canInvert(), "Sensor does not invert");
|
|
t.setState(Sensor.INACTIVE);
|
|
t.setInverted(true);
|
|
// check
|
|
assertEquals( Sensor.ACTIVE, t.getState(), "state 1");
|
|
assertEquals( "Active", t.describeState(t.getState()), "state 2");
|
|
}
|
|
|
|
@Test
|
|
public void testInvertAfterActive() throws JmriException {
|
|
assumeTrue(t.canInvert(), "Sensor does not invert");
|
|
t.setState(Sensor.ACTIVE);
|
|
t.setInverted(true);
|
|
// check
|
|
assertEquals( Sensor.INACTIVE, t.getState(), "state 1");
|
|
assertEquals( "Inactive", t.describeState(t.getState()), "state 2");
|
|
}
|
|
|
|
@Test
|
|
public void testDebounceSettings() throws JmriException {
|
|
t.setSensorDebounceGoingActiveTimer(81L);
|
|
assertEquals( 81L, t.getSensorDebounceGoingActiveTimer(), "timer");
|
|
|
|
t.setSensorDebounceGoingInActiveTimer(31L);
|
|
assertEquals( 31L, t.getSensorDebounceGoingInActiveTimer(), "timer");
|
|
|
|
assertFalse( t.getUseDefaultTimerSettings(), "initial default");
|
|
t.setUseDefaultTimerSettings(true);
|
|
assertTrue( t.getUseDefaultTimerSettings(), "initial default");
|
|
}
|
|
|
|
@Test
|
|
public void testDebounce() throws JmriException {
|
|
t.setSensorDebounceGoingActiveTimer(81L);
|
|
assertEquals( 81L, t.getSensorDebounceGoingActiveTimer(), "timer");
|
|
|
|
t.setSensorDebounceGoingInActiveTimer(31L);
|
|
assertEquals( 31L, t.getSensorDebounceGoingInActiveTimer(), "timer");
|
|
|
|
assertEquals( Sensor.UNKNOWN, t.getState(), "initial state");
|
|
t.setOwnState(Sensor.ACTIVE); // next is considered to run immediately, before debounce
|
|
assertEquals( Sensor.UNKNOWN, t.getState(), "post-set state");
|
|
JUnitUtil.waitFor(()-> t.getState() == t.getRawState(), "raw state = state");
|
|
assertEquals( Sensor.ACTIVE, t.getState(), "2nd state");
|
|
|
|
t.setOwnState(Sensor.INACTIVE); // next is considered to run immediately, before debounce
|
|
assertEquals( Sensor.ACTIVE, t.getState(), "post-set state");
|
|
JUnitUtil.waitFor(()-> t.getState() == t.getRawState(), "raw state = state");
|
|
assertEquals( Sensor.INACTIVE, t.getState(), "Final state");
|
|
|
|
disposeAndWaitForDebounceThread(t);
|
|
|
|
}
|
|
|
|
private void disposeAndWaitForDebounceThread(AbstractSensor t) {
|
|
Thread debounce = t.thr;
|
|
t.dispose();
|
|
if ( debounce !=null ) {
|
|
JUnitUtil.waitFor( ()-> { return !debounce.isAlive(); }, debounce.getName() + " did not close");
|
|
}
|
|
}
|
|
|
|
@Test
|
|
public void testGetPullResistance(){
|
|
// default is off, override this test if this is supported.
|
|
assertEquals( Sensor.PullResistance.PULL_OFF, t.getPullResistance(), "Pull Direction");
|
|
}
|
|
|
|
@Test
|
|
public void testGetBeanType(){
|
|
assertEquals( t.getBeanType(), Bundle.getMessage("BeanNameSensor"), "bean type");
|
|
}
|
|
|
|
// Test outgoing status request
|
|
@Test
|
|
public void testSensorStatusRequest() {
|
|
t.requestUpdateFromLayout();
|
|
// check that the correct message was sent
|
|
checkStatusRequestMsgSent();
|
|
}
|
|
|
|
// Test the Sensor interface
|
|
@Test
|
|
public void testSensor() throws JmriException {
|
|
t.setState(Sensor.ON);
|
|
JUnitUtil.waitFor( ()-> t.getState() == Sensor.ON, "state = ON");
|
|
assertEquals( Sensor.ON, t.getState(), "Sensor is ON");
|
|
t.setState(Sensor.OFF);
|
|
JUnitUtil.waitFor( ()-> t.getState() == Sensor.OFF, "state = OFF");
|
|
assertEquals( Sensor.OFF, t.getState(), "Sensor is OFF");
|
|
t.setCommandedState(Sensor.ON);
|
|
JUnitUtil.waitFor( ()-> t.getState() == Sensor.ON, "state = ON");
|
|
assertEquals( Sensor.ON, t.getState(), "Sensor is ON");
|
|
t.setCommandedState(Sensor.OFF);
|
|
JUnitUtil.waitFor( ()-> t.getState() == Sensor.OFF, "state = OFF");
|
|
assertEquals( Sensor.OFF, t.getState(), "Sensor is OFF");
|
|
t.setState(Sensor.ON);
|
|
JUnitUtil.waitFor( ()-> t.getCommandedState() == Sensor.ON, "commanded state = ON");
|
|
assertEquals( Sensor.ON, t.getCommandedState(), "Sensor is ON");
|
|
t.setState(Sensor.OFF);
|
|
JUnitUtil.waitFor( ()-> t.getCommandedState() == Sensor.OFF, "commanded state = OFF");
|
|
assertEquals( Sensor.OFF, t.getCommandedState(), "Sensor is ON");
|
|
}
|
|
|
|
@Test
|
|
public void testSensorSetKnownState() throws JmriException {
|
|
|
|
// Assert.assertEquals("ACTIVE", t.describeState(Sensor.ACTIVE), t.describeState(t.getState()));
|
|
|
|
t.setKnownState(Sensor.ACTIVE);
|
|
assertEquals( Sensor.ACTIVE, t.getState(), "ACTIVE");
|
|
|
|
t.setKnownState(Sensor.INACTIVE);
|
|
assertEquals( Sensor.INACTIVE, t.getState(), "INACTIVE");
|
|
|
|
t.setKnownState(Sensor.UNKNOWN);
|
|
assertEquals( Sensor.UNKNOWN, t.getState(), "UNKNOWN");
|
|
|
|
// Reset known state to something normal
|
|
t.setKnownState(Sensor.ACTIVE);
|
|
assertEquals( Sensor.ACTIVE, t.getState(), "ACTIVE");
|
|
|
|
t.setKnownState(Sensor.INCONSISTENT);
|
|
assertEquals( Sensor.INCONSISTENT, t.getState(), "INCONSISTENT");
|
|
}
|
|
|
|
//dispose of t.
|
|
abstract public void tearDown();
|
|
|
|
}
|