Skip to content

Commit 8c5bbd7

Browse files
rohitjoinscopybara-github
authored andcommitted
Migrate Mp3ExtractorTest to RobolectricTestParameterInjector
This allows for the deduplication of several tests that previously had identical bodies and only differed by the flags passed to the `Mp3Extractor` constructor. Test cases are now grouped into enums, which improves readability and makes the test suite easier to maintain. PiperOrigin-RevId: 819781672
1 parent d107936 commit 8c5bbd7

File tree

2 files changed

+129
-94
lines changed

2 files changed

+129
-94
lines changed

libraries/extractor/src/test/java/androidx/media3/extractor/mp3/Mp3ExtractorTest.java

Lines changed: 127 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -19,92 +19,91 @@
1919

2020
import androidx.media3.test.utils.ExtractorAsserts;
2121
import androidx.media3.test.utils.ExtractorAsserts.AssertionConfig;
22+
import com.google.common.base.Ascii;
2223
import com.google.common.collect.ImmutableList;
24+
import com.google.testing.junit.testparameterinjector.TestParameter;
25+
import com.google.testing.junit.testparameterinjector.TestParameterValuesProvider;
2326
import org.junit.Test;
2427
import org.junit.runner.RunWith;
25-
import org.robolectric.ParameterizedRobolectricTestRunner;
26-
import org.robolectric.ParameterizedRobolectricTestRunner.Parameter;
27-
import org.robolectric.ParameterizedRobolectricTestRunner.Parameters;
28+
import org.robolectric.RobolectricTestParameterInjector;
2829

2930
/** Unit test for {@link Mp3Extractor}. */
30-
@RunWith(ParameterizedRobolectricTestRunner.class)
31+
@RunWith(RobolectricTestParameterInjector.class)
3132
public final class Mp3ExtractorTest {
3233

33-
@Parameters(name = "{0}")
34-
public static ImmutableList<ExtractorAsserts.SimulationConfig> params() {
35-
return ExtractorAsserts.configs();
34+
private static final class SimulationConfigProvider extends TestParameterValuesProvider {
35+
@Override
36+
protected ImmutableList<ExtractorAsserts.SimulationConfig> provideValues(Context context) {
37+
return ExtractorAsserts.configs();
38+
}
3639
}
3740

38-
@Parameter public ExtractorAsserts.SimulationConfig simulationConfig;
41+
private enum XingHeaderFlagConfig {
42+
NONE(/* flags= */ 0),
43+
INDEX_SEEKING(Mp3Extractor.FLAG_ENABLE_INDEX_SEEKING);
3944

40-
@Test
41-
public void mp3SampleWithXingHeader() throws Exception {
42-
ExtractorAsserts.assertBehavior(
43-
Mp3Extractor::new,
44-
"media/mp3/bear-vbr-xing-header.mp3",
45-
/* peekLimit= */ 1300,
46-
simulationConfig);
45+
private final @Mp3Extractor.Flags int flags;
46+
47+
XingHeaderFlagConfig(@Mp3Extractor.Flags int flags) {
48+
this.flags = flags;
49+
}
4750
}
4851

4952
@Test
50-
public void mp3SampleWithXingHeader_indexSeekingFlag_usesXingSeeker() throws Exception {
53+
public void mp3SampleWithXingHeader(
54+
@TestParameter XingHeaderFlagConfig flagConfig,
55+
@TestParameter(valuesProvider = SimulationConfigProvider.class)
56+
ExtractorAsserts.SimulationConfig simulationConfig)
57+
throws Exception {
5158
ExtractorAsserts.assertBehavior(
52-
() -> new Mp3Extractor(Mp3Extractor.FLAG_ENABLE_INDEX_SEEKING),
59+
() -> new Mp3Extractor(flagConfig.flags),
5360
"media/mp3/bear-vbr-xing-header.mp3",
5461
/* peekLimit= */ 1300,
5562
simulationConfig);
5663
}
5764

58-
@Test
59-
public void mp3SampleWithXingHeader_noTableOfContents() throws Exception {
60-
ExtractorAsserts.assertBehavior(
61-
Mp3Extractor::new,
62-
"media/mp3/bear-vbr-xing-header-no-toc.mp3",
63-
/* peekLimit= */ 1300,
64-
simulationConfig);
65-
}
65+
private enum XingHeaderNoTocFlagConfig {
66+
NONE(/* flags= */ 0),
67+
INDEX_SEEKING(Mp3Extractor.FLAG_ENABLE_INDEX_SEEKING),
68+
CBR_SEEKING(Mp3Extractor.FLAG_ENABLE_CONSTANT_BITRATE_SEEKING),
69+
CBR_SEEKING_ALWAYS(Mp3Extractor.FLAG_ENABLE_CONSTANT_BITRATE_SEEKING_ALWAYS);
6670

67-
@Test
68-
public void mp3SampleWithXingHeader_noTableOfContents_indexSeeking() throws Exception {
69-
String filename = "mp3/bear-vbr-xing-header-no-toc.mp3";
70-
ExtractorAsserts.assertBehavior(
71-
() -> new Mp3Extractor(Mp3Extractor.FLAG_ENABLE_INDEX_SEEKING),
72-
"media/" + filename,
73-
/* peekLimit= */ 1300,
74-
new AssertionConfig.Builder()
75-
.setDumpFilesPrefix("extractordumps/" + filename + ".index-seeking")
76-
.build(),
77-
simulationConfig);
78-
}
71+
private final @Mp3Extractor.Flags int flags;
7972

80-
@Test
81-
public void mp3SampleWithXingHeader_noTableOfContents_cbrSeeking() throws Exception {
82-
String filename = "mp3/bear-vbr-xing-header-no-toc.mp3";
83-
ExtractorAsserts.assertBehavior(
84-
() -> new Mp3Extractor(Mp3Extractor.FLAG_ENABLE_CONSTANT_BITRATE_SEEKING),
85-
"media/" + filename,
86-
/* peekLimit= */ 1300,
87-
new AssertionConfig.Builder()
88-
.setDumpFilesPrefix("extractordumps/" + filename + ".cbr-seeking")
89-
.build(),
90-
simulationConfig);
73+
XingHeaderNoTocFlagConfig(@Mp3Extractor.Flags int flags) {
74+
this.flags = flags;
75+
}
9176
}
9277

9378
@Test
94-
public void mp3SampleWithXingHeader_noTableOfContents_cbrSeekingAlways() throws Exception {
95-
String filename = "mp3/bear-vbr-xing-header-no-toc.mp3";
79+
public void mp3SampleWithXingHeader_noTableOfContents(
80+
@TestParameter XingHeaderNoTocFlagConfig flagConfig,
81+
@TestParameter(valuesProvider = SimulationConfigProvider.class)
82+
ExtractorAsserts.SimulationConfig simulationConfig)
83+
throws Exception {
84+
String inputFilePath = "media/mp3/bear-vbr-xing-header-no-toc.mp3";
85+
String dumpFilePrefix;
86+
if (!flagConfig.equals(XingHeaderNoTocFlagConfig.NONE)) {
87+
dumpFilePrefix =
88+
inputFilePath.replaceFirst("media", "extractordumps")
89+
+ "."
90+
+ Ascii.toLowerCase(flagConfig.name()).replace('_', '-');
91+
} else {
92+
dumpFilePrefix = null;
93+
}
9694
ExtractorAsserts.assertBehavior(
97-
() -> new Mp3Extractor(Mp3Extractor.FLAG_ENABLE_CONSTANT_BITRATE_SEEKING_ALWAYS),
98-
"media/" + filename,
95+
() -> new Mp3Extractor(flagConfig.flags),
96+
inputFilePath,
9997
/* peekLimit= */ 1300,
100-
new AssertionConfig.Builder()
101-
.setDumpFilesPrefix("extractordumps/" + filename + ".cbr-seeking-always")
102-
.build(),
98+
new AssertionConfig.Builder().setDumpFilesPrefix(dumpFilePrefix).build(),
10399
simulationConfig);
104100
}
105101

106102
@Test
107-
public void mp3SampleWithInfoHeader() throws Exception {
103+
public void mp3SampleWithInfoHeader(
104+
@TestParameter(valuesProvider = SimulationConfigProvider.class)
105+
ExtractorAsserts.SimulationConfig simulationConfig)
106+
throws Exception {
108107
ExtractorAsserts.assertBehavior(
109108
Mp3Extractor::new,
110109
"media/mp3/test-cbr-info-header.mp3",
@@ -114,7 +113,10 @@ public void mp3SampleWithInfoHeader() throws Exception {
114113

115114
// https://github.com/androidx/media/issues/1376#issuecomment-2117393653
116115
@Test
117-
public void mp3SampleWithInfoHeaderAndPcutFrame() throws Exception {
116+
public void mp3SampleWithInfoHeaderAndPcutFrame(
117+
@TestParameter(valuesProvider = SimulationConfigProvider.class)
118+
ExtractorAsserts.SimulationConfig simulationConfig)
119+
throws Exception {
118120
ExtractorAsserts.assertBehavior(
119121
Mp3Extractor::new,
120122
"media/mp3/test-cbr-info-header-pcut-frame.mp3",
@@ -124,7 +126,10 @@ public void mp3SampleWithInfoHeaderAndPcutFrame() throws Exception {
124126

125127
// https://github.com/androidx/media/issues/1480
126128
@Test
127-
public void mp3SampleWithInfoHeaderAndTrailingGarbage() throws Exception {
129+
public void mp3SampleWithInfoHeaderAndTrailingGarbage(
130+
@TestParameter(valuesProvider = SimulationConfigProvider.class)
131+
ExtractorAsserts.SimulationConfig simulationConfig)
132+
throws Exception {
128133
// This test file is test-cbr-info-header.mp3 with 150kB of 0xDEADBEEF garbage appended on the
129134
// end. The test asserts that the extracted samples are the same as for
130135
// test-cbr-info-header.mp3.
@@ -139,7 +144,10 @@ public void mp3SampleWithInfoHeaderAndTrailingGarbage() throws Exception {
139144
}
140145

141146
@Test
142-
public void mp3SampleWithVbriHeader() throws Exception {
147+
public void mp3SampleWithVbriHeader(
148+
@TestParameter(valuesProvider = SimulationConfigProvider.class)
149+
ExtractorAsserts.SimulationConfig simulationConfig)
150+
throws Exception {
143151
ExtractorAsserts.assertBehavior(
144152
Mp3Extractor::new,
145153
"media/mp3/bear-vbr-vbri-header.mp3",
@@ -149,37 +157,51 @@ public void mp3SampleWithVbriHeader() throws Exception {
149157

150158
// https://github.com/androidx/media/issues/1904
151159
@Test
152-
public void mp3SampleWithVbriHeaderWithTruncatedToC() throws Exception {
160+
public void mp3SampleWithVbriHeaderWithTruncatedToC(
161+
@TestParameter(valuesProvider = SimulationConfigProvider.class)
162+
ExtractorAsserts.SimulationConfig simulationConfig)
163+
throws Exception {
153164
ExtractorAsserts.assertBehavior(
154165
Mp3Extractor::new,
155166
"media/mp3/bear-vbr-vbri-header-truncated-toc.mp3",
156167
/* peekLimit= */ 1300,
157168
simulationConfig);
158169
}
159170

160-
@Test
161-
public void mp3SampleWithCbrSeeker() throws Exception {
162-
ExtractorAsserts.assertBehavior(
163-
Mp3Extractor::new,
164-
"media/mp3/bear-cbr-variable-frame-size-no-seek-table.mp3",
165-
/* peekLimit= */ 1500,
166-
simulationConfig);
171+
private enum CbrSeekerFlagConfig {
172+
DEFAULT(/* flags= */ 0),
173+
CBR_SEEKING_ALWAYS(Mp3Extractor.FLAG_ENABLE_CONSTANT_BITRATE_SEEKING_ALWAYS);
174+
175+
private final @Mp3Extractor.Flags int flags;
176+
177+
CbrSeekerFlagConfig(@Mp3Extractor.Flags int flags) {
178+
this.flags = flags;
179+
}
167180
}
168181

169182
@Test
170-
public void mp3SampleWithCbrSeekingAlwaysEnabled() throws Exception {
183+
public void mp3SampleWithCbrSeeker(
184+
@TestParameter CbrSeekerFlagConfig flagConfig,
185+
@TestParameter(valuesProvider = SimulationConfigProvider.class)
186+
ExtractorAsserts.SimulationConfig simulationConfig)
187+
throws Exception {
188+
String dumpFilePrefix =
189+
flagConfig == CbrSeekerFlagConfig.CBR_SEEKING_ALWAYS
190+
? "extractordumps/mp3/bear-cbr_cbr-seeking-always-enabled"
191+
: null;
171192
ExtractorAsserts.assertBehavior(
172-
() -> new Mp3Extractor(Mp3Extractor.FLAG_ENABLE_CONSTANT_BITRATE_SEEKING_ALWAYS),
193+
() -> new Mp3Extractor(flagConfig.flags),
173194
"media/mp3/bear-cbr-variable-frame-size-no-seek-table.mp3",
174195
/* peekLimit= */ 1500,
175-
new AssertionConfig.Builder()
176-
.setDumpFilesPrefix("extractordumps/mp3/bear-cbr_cbr-seeking-always-enabled")
177-
.build(),
196+
new AssertionConfig.Builder().setDumpFilesPrefix(dumpFilePrefix).build(),
178197
simulationConfig);
179198
}
180199

181200
@Test
182-
public void mp3SampleWithIndexSeeker() throws Exception {
201+
public void mp3SampleWithIndexSeeker(
202+
@TestParameter(valuesProvider = SimulationConfigProvider.class)
203+
ExtractorAsserts.SimulationConfig simulationConfig)
204+
throws Exception {
183205
ExtractorAsserts.assertBehavior(
184206
() -> new Mp3Extractor(Mp3Extractor.FLAG_ENABLE_INDEX_SEEKING),
185207
"media/mp3/bear-vbr-no-seek-table.mp3",
@@ -189,7 +211,10 @@ public void mp3SampleWithIndexSeeker() throws Exception {
189211

190212
// https://github.com/androidx/media/issues/1563
191213
@Test
192-
public void mp3CbrSampleWithNoSeekTableAndTrailingGarbage() throws Exception {
214+
public void mp3CbrSampleWithNoSeekTableAndTrailingGarbage(
215+
@TestParameter(valuesProvider = SimulationConfigProvider.class)
216+
ExtractorAsserts.SimulationConfig simulationConfig)
217+
throws Exception {
193218
assumeFalse(
194219
"Skipping I/O error testing with unknown length due to b/362727473",
195220
simulationConfig.simulateIOErrors && simulationConfig.simulateUnknownLength);
@@ -201,37 +226,48 @@ public void mp3CbrSampleWithNoSeekTableAndTrailingGarbage() throws Exception {
201226
}
202227

203228
@Test
204-
public void trimmedMp3Sample() throws Exception {
229+
public void trimmedMp3Sample(
230+
@TestParameter(valuesProvider = SimulationConfigProvider.class)
231+
ExtractorAsserts.SimulationConfig simulationConfig)
232+
throws Exception {
205233
ExtractorAsserts.assertBehavior(
206234
Mp3Extractor::new, "media/mp3/play-trimmed.mp3", /* peekLimit= */ 1200, simulationConfig);
207235
}
208236

209-
@Test
210-
public void mp3SampleWithId3Enabled() throws Exception {
211-
ExtractorAsserts.assertBehavior(
212-
Mp3Extractor::new,
213-
"media/mp3/bear-id3.mp3",
214-
/* peekLimit= */ 41_000,
215-
new AssertionConfig.Builder()
216-
.setDumpFilesPrefix("extractordumps/mp3/bear-id3-enabled")
217-
.build(),
218-
simulationConfig);
237+
private enum Id3FlagConfig {
238+
ENABLED(/* flags= */ 0),
239+
DISABLED(Mp3Extractor.FLAG_DISABLE_ID3_METADATA);
240+
241+
private final @Mp3Extractor.Flags int flags;
242+
243+
Id3FlagConfig(@Mp3Extractor.Flags int flags) {
244+
this.flags = flags;
245+
}
219246
}
220247

221248
@Test
222-
public void mp3SampleWithId3Disabled() throws Exception {
249+
public void mp3SampleWithId3(
250+
@TestParameter Id3FlagConfig flagConfig,
251+
@TestParameter(valuesProvider = SimulationConfigProvider.class)
252+
ExtractorAsserts.SimulationConfig simulationConfig)
253+
throws Exception {
254+
String dumpFilePrefix =
255+
flagConfig == Id3FlagConfig.ENABLED
256+
? "extractordumps/mp3/bear-id3-enabled"
257+
: "extractordumps/mp3/bear-id3-disabled";
223258
ExtractorAsserts.assertBehavior(
224-
() -> new Mp3Extractor(Mp3Extractor.FLAG_DISABLE_ID3_METADATA),
259+
() -> new Mp3Extractor(flagConfig.flags),
225260
"media/mp3/bear-id3.mp3",
226261
/* peekLimit= */ 41_000,
227-
new AssertionConfig.Builder()
228-
.setDumpFilesPrefix("extractordumps/mp3/bear-id3-disabled")
229-
.build(),
262+
new AssertionConfig.Builder().setDumpFilesPrefix(dumpFilePrefix).build(),
230263
simulationConfig);
231264
}
232265

233266
@Test
234-
public void mp3SampleWithId3NumericGenre() throws Exception {
267+
public void mp3SampleWithId3NumericGenre(
268+
@TestParameter(valuesProvider = SimulationConfigProvider.class)
269+
ExtractorAsserts.SimulationConfig simulationConfig)
270+
throws Exception {
235271
ExtractorAsserts.assertBehavior(
236272
Mp3Extractor::new,
237273
"media/mp3/bear-id3-numeric-genre.mp3",

libraries/test_utils/src/main/java/androidx/media3/test/utils/ExtractorAsserts.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@
3737
import java.io.IOException;
3838
import java.util.Arrays;
3939
import java.util.List;
40-
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
4140

4241
/** Assertion methods for {@link Extractor}. */
4342
@UnstableApi
@@ -148,11 +147,11 @@ private AssertionConfig(
148147

149148
/** Builder for {@link AssertionConfig} instances. */
150149
public static class Builder {
151-
private @MonotonicNonNull String dumpFilesPrefix;
150+
@Nullable private String dumpFilesPrefix;
152151
private boolean deduplicateConsecutiveFormats;
153152

154153
@CanIgnoreReturnValue
155-
public Builder setDumpFilesPrefix(String dumpFilesPrefix) {
154+
public Builder setDumpFilesPrefix(@Nullable String dumpFilesPrefix) {
156155
this.dumpFilesPrefix = dumpFilesPrefix;
157156
return this;
158157
}

0 commit comments

Comments
 (0)