Skip to content

Commit be81218

Browse files
authored
Add async media sample unit tests (#4165)
* Add async media sample unit tests * Fix async media test to use Label
1 parent 5933b21 commit be81218

File tree

2 files changed

+216
-0
lines changed

2 files changed

+216
-0
lines changed
Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
package com.codename1.media;
2+
3+
import com.codename1.junit.FormTest;
4+
import com.codename1.junit.UITestBase;
5+
import com.codename1.ui.Button;
6+
import com.codename1.ui.CN;
7+
import com.codename1.ui.Form;
8+
import com.codename1.ui.Label;
9+
import com.codename1.ui.Slider;
10+
import com.codename1.ui.events.ActionListener;
11+
import com.codename1.ui.events.MessageEvent;
12+
import com.codename1.ui.layouts.BorderLayout;
13+
import com.codename1.ui.layouts.LayeredLayout;
14+
import com.codename1.util.SuccessCallback;
15+
16+
import static org.junit.jupiter.api.Assertions.*;
17+
18+
class AsyncMediaSampleTest extends UITestBase {
19+
20+
@FormTest
21+
void promptMessagesCompletePromptPromiseAndAreConsumed() {
22+
AsyncMediaSampleHarness harness = new AsyncMediaSampleHarness(true);
23+
Form form = new Form();
24+
harness.initUI(form);
25+
26+
final boolean[] resolved = new boolean[1];
27+
MessageEvent.PromptPromise promptPromise = new MessageEvent.PromptPromise();
28+
promptPromise.ready(new SuccessCallback<Boolean>() {
29+
public void onSucess(Boolean arg) {
30+
resolved[0] = arg != null && arg.booleanValue();
31+
}
32+
});
33+
34+
MessageEvent evt = implementation.fireMessageEvent(promptPromise, "", 426);
35+
flushSerialCalls();
36+
37+
assertTrue(evt.isConsumed());
38+
assertTrue(resolved[0]);
39+
}
40+
41+
@FormTest
42+
void playMessageStartsRecordingAndDisablesPlayButton() {
43+
AsyncMediaSampleHarness harness = new AsyncMediaSampleHarness(true);
44+
Form form = new Form();
45+
harness.initUI(form);
46+
47+
implementation.fireMessageEvent(this, "play", 0);
48+
49+
assertEquals(1, harness.getRecordRequests());
50+
assertTrue(harness.getPauseButton().isEnabled());
51+
assertTrue(harness.getPauseButton().isVisible());
52+
assertFalse(harness.getPlayButton().isEnabled());
53+
assertFalse(harness.getPlayButton().isVisible());
54+
}
55+
56+
@FormTest
57+
void pauseMessageStopsRecordingAndRestoresPlayButton() {
58+
AsyncMediaSampleHarness harness = new AsyncMediaSampleHarness(true);
59+
Form form = new Form();
60+
harness.initUI(form);
61+
62+
implementation.fireMessageEvent(this, "play", 0);
63+
implementation.fireMessageEvent(this, "pause", 0);
64+
65+
assertEquals(1, harness.getPauseRequests());
66+
assertEquals("Paused", harness.getStatus().getText());
67+
assertEquals("Press play to begin", harness.getInstructions().getText());
68+
assertFalse(harness.getPauseButton().isVisible());
69+
assertFalse(harness.getPauseButton().isEnabled());
70+
assertTrue(harness.getPlayButton().isVisible());
71+
assertTrue(harness.getPlayButton().isEnabled());
72+
}
73+
74+
private static class AsyncMediaSampleHarness {
75+
private final Slider slider = new Slider();
76+
private final Label status = new Label();
77+
private final Label instructions = new Label();
78+
private final Button pause = new Button("Pause");
79+
private final Button play = new Button("Play");
80+
private final boolean promptResponse;
81+
private int recordRequests;
82+
private int pauseRequests;
83+
84+
AsyncMediaSampleHarness(boolean promptResponse) {
85+
this.promptResponse = promptResponse;
86+
}
87+
88+
void initUI(Form form) {
89+
pause.addActionListener(evt -> {
90+
pause();
91+
status.setText("Paused");
92+
pause.setEnabled(false);
93+
play.setEnabled(true);
94+
play.setVisible(true);
95+
pause.setVisible(false);
96+
instructions.setText("Press play to begin");
97+
98+
});
99+
100+
play.addActionListener(evt -> {
101+
pause.setEnabled(true);
102+
play.setEnabled(false);
103+
play.setVisible(false);
104+
pause.setVisible(true);
105+
record();
106+
107+
});
108+
CN.addMessageListener((ActionListener<MessageEvent>) evt -> {
109+
if (evt.isPromptForAudioPlayer()) {
110+
evt.consume();
111+
CN.callSerially(new Runnable() {
112+
public void run() {
113+
MessageEvent.PromptPromise res = evt.getPromptPromise();
114+
if (res != null) {
115+
res.complete(Boolean.valueOf(promptResponse));
116+
}
117+
}
118+
});
119+
return;
120+
121+
}
122+
123+
if (evt.isPromptForAudioRecorder()) {
124+
evt.consume();
125+
CN.callSerially(new Runnable() {
126+
public void run() {
127+
MessageEvent.PromptPromise res = evt.getPromptPromise();
128+
if (res != null) {
129+
res.complete(Boolean.valueOf(promptResponse));
130+
}
131+
}
132+
});
133+
return;
134+
135+
}
136+
137+
String message = evt.getMessage();
138+
if ("play".equals(message)) {
139+
pause.setEnabled(true);
140+
play.setEnabled(false);
141+
play.setVisible(false);
142+
pause.setVisible(true);
143+
record();
144+
return;
145+
}
146+
if ("pause".equals(message)) {
147+
pause();
148+
status.setText("Paused");
149+
pause.setEnabled(false);
150+
play.setEnabled(true);
151+
play.setVisible(true);
152+
pause.setVisible(false);
153+
instructions.setText("Press play to begin");
154+
return;
155+
}
156+
});
157+
form.setLayout(new BorderLayout());
158+
form.add(BorderLayout.CENTER, LayeredLayout.encloseIn(pause, play));
159+
form.add(BorderLayout.SOUTH, BorderLayout.south(slider).add(BorderLayout.CENTER, status));
160+
form.add(BorderLayout.NORTH, instructions);
161+
instructions.setText("Press play to begin");
162+
pause.setVisible(false);
163+
pause.setEnabled(false);
164+
slider.setEditable(false);
165+
}
166+
167+
int getRecordRequests() {
168+
return recordRequests;
169+
}
170+
171+
int getPauseRequests() {
172+
return pauseRequests;
173+
}
174+
175+
Button getPauseButton() {
176+
return pause;
177+
}
178+
179+
Button getPlayButton() {
180+
return play;
181+
}
182+
183+
Label getStatus() {
184+
return status;
185+
}
186+
187+
Label getInstructions() {
188+
return instructions;
189+
}
190+
191+
private void pause() {
192+
pauseRequests++;
193+
}
194+
195+
private void record() {
196+
recordRequests++;
197+
}
198+
}
199+
}

maven/core-unittests/src/test/java/com/codename1/testing/TestCodenameOneImplementation.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import com.codename1.ui.TextSelection;
3131
import com.codename1.ui.events.ActionEvent;
3232
import com.codename1.ui.events.ActionListener;
33+
import com.codename1.ui.events.MessageEvent;
3334
import com.codename1.ui.geom.Dimension;
3435
import com.codename1.ui.util.ImageIO;
3536
import com.codename1.ui.geom.Rectangle;
@@ -2187,6 +2188,22 @@ public Message getLastSentMessage() {
21872188
return lastSentMessage;
21882189
}
21892190

2191+
/**
2192+
* Dispatches a {@link MessageEvent} through the current display. This mirrors how
2193+
* native ports forward messages into the Codename One runtime so that tests can
2194+
* exercise message listeners without bypassing the platform entry point.
2195+
*
2196+
* @param source event source
2197+
* @param message message payload
2198+
* @param code event code
2199+
* @return the dispatched event
2200+
*/
2201+
public MessageEvent fireMessageEvent(Object source, String message, int code) {
2202+
MessageEvent evt = new MessageEvent(source, message, code);
2203+
Display.getInstance().dispatchMessage(evt);
2204+
return evt;
2205+
}
2206+
21902207
@Override
21912208
public void scheduleLocalNotification(LocalNotification notif, long firstTime, int repeat) {
21922209
if (notif == null) {

0 commit comments

Comments
 (0)