Skip to content

Commit 2cd7744

Browse files
authoredFeb 24, 2025··
Merge branch 'main' into 310-add-missing-documentation-includes-in-indexadoc
2 parents 6bf6d33 + d33f47a commit 2cd7744

File tree

2 files changed

+259
-0
lines changed

2 files changed

+259
-0
lines changed
 
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
import static org.mockito.ArgumentMatchers.any;
2+
import static org.mockito.Mockito.*;
3+
import static org.junit.jupiter.api.Assertions.*;
4+
5+
import com.pi4j.io.gpio.digital.DigitalInput;
6+
import com.pi4j.io.gpio.digital.DigitalStateChangeListener;
7+
import com.opensourcewithslu.inputdevices.PIRSensorHelper;
8+
import java.io.ByteArrayOutputStream;
9+
import java.io.PrintStream;
10+
import java.util.concurrent.atomic.AtomicBoolean;
11+
12+
import org.junit.jupiter.api.BeforeEach;
13+
import org.junit.jupiter.api.Test;
14+
import org.mockito.ArgumentCaptor;
15+
16+
class PIRSensorHelperTest {
17+
private DigitalInput pirSensorInput;
18+
private PIRSensorHelper pirSensorHelper;
19+
20+
@BeforeEach
21+
void setUp() {
22+
pirSensorInput = mock(DigitalInput.class);
23+
when(pirSensorInput.isHigh()).thenReturn(true);
24+
pirSensorHelper = new PIRSensorHelper(pirSensorInput);
25+
}
26+
27+
@Test
28+
void testIsMovingFieldSetCorrectlyWhenInputIsHigh() {
29+
when(pirSensorInput.isHigh()).thenReturn(true);
30+
pirSensorHelper = new PIRSensorHelper(pirSensorInput);
31+
assertTrue(pirSensorHelper.isMoving, "Expected isMoving to be true when PIR sensor detects motion (DigitalInput is high)");
32+
}
33+
34+
@Test
35+
void testIsMovingFieldSetCorrectlyWhenInputIsLow() {
36+
when(pirSensorInput.isHigh()).thenReturn(false);
37+
pirSensorHelper = new PIRSensorHelper(pirSensorInput);
38+
assertFalse(pirSensorHelper.isMoving, "Expected isMoving to be true when PIR sensor detects motion (DigitalInput is low)");
39+
}
40+
41+
@Test
42+
void testInitializationLogsCaptureSystemOut() {
43+
PrintStream originalOut = System.out;
44+
ByteArrayOutputStream baos = new ByteArrayOutputStream();
45+
PrintStream ps = new PrintStream(baos);
46+
System.setOut(ps);
47+
try {
48+
when(pirSensorInput.isHigh()).thenReturn(true);
49+
new PIRSensorHelper(pirSensorInput);
50+
ps.flush();
51+
String output = baos.toString();
52+
assertTrue(output.contains("Initializing PIR Sensor"),
53+
"Expected log message 'Initializing PIR Sensor' was not found in System.out output.");
54+
} finally {
55+
System.setOut(originalOut);
56+
}
57+
}
58+
59+
@Test
60+
void testAddEventListener() {
61+
DigitalStateChangeListener dummyListener = mock(DigitalStateChangeListener.class);
62+
pirSensorHelper.addEventListener(dummyListener);
63+
pirSensorHelper.removeEventListener();
64+
verify(pirSensorInput).removeListener(dummyListener);
65+
}
66+
67+
@Test
68+
void testCustomListenerInvocation() {
69+
AtomicBoolean listenerInvoked = new AtomicBoolean(false);
70+
DigitalStateChangeListener listener = event -> listenerInvoked.set(true);
71+
pirSensorHelper.addEventListener(listener);
72+
listener.onDigitalStateChange(null);
73+
assertTrue(listenerInvoked.get(), "The custom listener should have been invoked.");
74+
}
75+
76+
@Test
77+
void testInternalListenerUpdatesIsMoving() {
78+
ArgumentCaptor<DigitalStateChangeListener> captor = ArgumentCaptor.forClass(DigitalStateChangeListener.class);
79+
verify(pirSensorInput, atLeastOnce()).addListener(captor.capture());
80+
DigitalStateChangeListener internalListener = captor.getAllValues().get(0);
81+
82+
when(pirSensorInput.isHigh()).thenReturn(false);
83+
internalListener.onDigitalStateChange(null);
84+
assertFalse(pirSensorHelper.isMoving, "Expected isMoving to update to false after state change.");
85+
86+
when(pirSensorInput.isHigh()).thenReturn(true);
87+
internalListener.onDigitalStateChange(null);
88+
assertTrue(pirSensorHelper.isMoving, "Expected isMoving to update to true after state change.");
89+
}
90+
91+
@Test
92+
void testMultipleRemoveEventListenerCalls() {
93+
pirSensorHelper.removeEventListener();
94+
pirSensorHelper.removeEventListener();
95+
verify(pirSensorInput, times(1)).removeListener(any());
96+
}
97+
98+
@Test
99+
void testAddEventListenerOverridesExistingListener() {
100+
DigitalStateChangeListener firstListener = mock(DigitalStateChangeListener.class);
101+
DigitalStateChangeListener secondListener = mock(DigitalStateChangeListener.class);
102+
103+
pirSensorHelper.addEventListener(firstListener);
104+
pirSensorHelper.addEventListener(secondListener);
105+
106+
ArgumentCaptor<DigitalStateChangeListener> captor = ArgumentCaptor.forClass(DigitalStateChangeListener.class);
107+
verify(pirSensorInput, atLeast(2)).addListener(captor.capture());
108+
109+
DigitalStateChangeListener lastAdded = captor.getAllValues().get(captor.getAllValues().size() - 1);
110+
assertSame(secondListener, lastAdded, "The new listener should override the previous listener.");
111+
112+
pirSensorHelper.removeEventListener();
113+
verify(pirSensorInput, times(1)).removeListener(secondListener);
114+
115+
}
116+
117+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
package com.opensourcewithslu.inputdevices;
2+
import static org.junit.jupiter.api.Assertions.*;
3+
import static org.mockito.Mockito.*;
4+
5+
import com.opensourcewithslu.mock.MockDigitalInput;
6+
import com.pi4j.io.gpio.digital.*;
7+
import org.junit.jupiter.api.BeforeEach;
8+
import org.junit.jupiter.api.Test;
9+
import org.slf4j.Logger;
10+
import org.slf4j.LoggerFactory;
11+
import java.lang.reflect.Field;
12+
13+
public class PhotoResistorHelperTest{
14+
private MockDigitalInput mockDigitalInput;
15+
private DigitalOutput mockDigitalOutput;
16+
private PhotoResistorHelper photoResistorHelper;
17+
18+
@BeforeEach
19+
public void setup(){
20+
mockDigitalInput = new MockDigitalInput();
21+
mockDigitalOutput = mock(DigitalOutput.class);
22+
photoResistorHelper = new PhotoResistorHelper(mockDigitalInput,mockDigitalOutput);
23+
}
24+
25+
@Test
26+
public void testInitializationLogic() {
27+
mockDigitalInput.SetState(DigitalState.LOW);
28+
PhotoResistorHelper helperLow = new PhotoResistorHelper(mockDigitalInput, mockDigitalOutput);
29+
assertFalse(helperLow.isDark);
30+
31+
mockDigitalInput.SetState(DigitalState.HIGH);
32+
PhotoResistorHelper helperHigh = new PhotoResistorHelper(mockDigitalInput, mockDigitalOutput);
33+
assertTrue(helperHigh.isDark);
34+
}
35+
36+
@Test
37+
public void testDarknessLevelCalculation() throws Exception {
38+
PhotoResistorHelper helper = new PhotoResistorHelper(mockDigitalInput, mockDigitalOutput);
39+
40+
helper.setDarknessThreshold(50);
41+
42+
Field startTimeField = PhotoResistorHelper.class.getDeclaredField("startTime");
43+
startTimeField.setAccessible(true);
44+
startTimeField.setLong(helper, System.currentTimeMillis() - 100);
45+
46+
helper.updateDark();
47+
48+
Field endTimeField = PhotoResistorHelper.class.getDeclaredField("endTime");
49+
endTimeField.setAccessible(true);
50+
endTimeField.setLong(helper, System.currentTimeMillis());
51+
52+
Field darknessField = PhotoResistorHelper.class.getDeclaredField("darknessValue");
53+
darknessField.setAccessible(true);
54+
int darknessValue = (int) (endTimeField.getLong(helper) - startTimeField.getLong(helper));
55+
darknessField.setInt(helper, darknessValue);
56+
57+
assertTrue(darknessValue > 0);
58+
59+
Field isDarkField = PhotoResistorHelper.class.getDeclaredField("isDark");
60+
isDarkField.setAccessible(true);
61+
isDarkField.setBoolean(helper, darknessValue > 50);
62+
63+
boolean isDark = isDarkField.getBoolean(helper);
64+
assertTrue(isDark);
65+
}
66+
67+
@Test
68+
public void testGetDark() throws Exception {
69+
PhotoResistorHelper helper = new PhotoResistorHelper(mockDigitalInput, mockDigitalOutput);
70+
71+
Field darknessField = PhotoResistorHelper.class.getDeclaredField("darknessValue");
72+
darknessField.setAccessible(true);
73+
darknessField.setInt(helper, 157);
74+
75+
assertEquals(157, helper.getDark());
76+
}
77+
78+
@Test
79+
public void testSetToLow() {
80+
mockDigitalInput.SetState(DigitalState.HIGH);
81+
PhotoResistorHelper helper = new PhotoResistorHelper(mockDigitalInput, mockDigitalOutput);
82+
83+
helper.setToLow();
84+
verify(mockDigitalOutput).low();
85+
}
86+
87+
@Test
88+
public void testSetDarknessThreshold() throws Exception {
89+
PhotoResistorHelper helper = new PhotoResistorHelper(mockDigitalInput, mockDigitalOutput);
90+
helper.setDarknessThreshold(300);
91+
92+
Field thresholdField = PhotoResistorHelper.class.getDeclaredField("darknessThreshold");
93+
thresholdField.setAccessible(true);
94+
int actualThreshold = thresholdField.getInt(helper);
95+
96+
assertEquals(300, actualThreshold);
97+
}
98+
99+
@Test
100+
public void testEventListenerManagement() {
101+
DigitalInput mockInput = mock(DigitalInput.class);
102+
PhotoResistorHelper helper = new PhotoResistorHelper(mockInput, mockDigitalOutput);
103+
DigitalStateChangeListener mockListener = mock(DigitalStateChangeListener.class);
104+
105+
helper.addEventListener(mockListener);
106+
verify(mockInput, times(1)).addListener(mockListener);
107+
108+
helper.removeEventListener();
109+
verify(mockInput, times(1)).removeListener(mockListener);
110+
}
111+
112+
@Test
113+
public void testEdgeCases() throws Exception {
114+
PhotoResistorHelper helper = new PhotoResistorHelper(mockDigitalInput, mockDigitalOutput);
115+
116+
helper.removeEventListener();
117+
helper.initialize();
118+
119+
long fakeStartTime = System.currentTimeMillis() - 600;
120+
long fakeEndTime = System.currentTimeMillis();
121+
122+
Field startTimeField = PhotoResistorHelper.class.getDeclaredField("startTime");
123+
startTimeField.setAccessible(true);
124+
startTimeField.setLong(helper, fakeStartTime);
125+
126+
Field endTimeField = PhotoResistorHelper.class.getDeclaredField("endTime");
127+
endTimeField.setAccessible(true);
128+
endTimeField.setLong(helper, fakeEndTime);
129+
130+
Field darknessField = PhotoResistorHelper.class.getDeclaredField("darknessValue");
131+
darknessField.setAccessible(true);
132+
int expectedDarkness = (int) (fakeEndTime - fakeStartTime);
133+
darknessField.setInt(helper, expectedDarkness);
134+
135+
assertEquals(expectedDarkness, helper.getDark());
136+
137+
assertDoesNotThrow(() -> {
138+
helper.removeEventListener();
139+
helper.removeEventListener();
140+
});
141+
}
142+
}

0 commit comments

Comments
 (0)
Please sign in to comment.