Adds tests for API

This commit is contained in:
Guillaume Tâche
2024-08-09 21:18:47 +02:00
parent 155b011c2b
commit 428edcd806
17 changed files with 515 additions and 41 deletions

View File

@@ -5,10 +5,20 @@ import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
/**
* Represents a file
*/
public interface File {
/**
* @return The file input stream
* @throws IOException If an I/O error occurs
*/
default InputStream getInputStream() throws IOException {
return Files.newInputStream(path());
}
/**
* @return The file path
*/
Path path();
}

View File

@@ -56,6 +56,7 @@ public enum Language {
final Map<String, Language> map = new java.util.HashMap<>();
for (final var language : Language.values()) {
map.put(language.name().toLowerCase(), language);
map.put(language.englishName.toLowerCase(), language);
map.put(language.iso2, language);
map.put(language.iso3, language);
language.aliases.forEach(s -> map.put(s, language));
@@ -75,22 +76,40 @@ public enum Language {
this.aliases = Set.of(aliases);
}
/**
* @return The name of the language in english
*/
public String englishName() {
return englishName;
}
/**
* @return The ISO 639-1 code
*/
public String iso2() {
return iso2;
}
/**
* @return The ISO 639-3 code
*/
public String iso3() {
return iso3;
}
/**
* Returns the language corresponding to the given name
*
* @param name The name (either ISO 639-1 or ISO 639-3 or english name)
* @return The language, or null if not found
*/
public static Language getLanguage(final String name) {
return STRING_LANGUAGE_MAP.get(name.toLowerCase());
}
/**
* @return The default language for the current locale, or english if not found
*/
public static Language getDefault() {
return STRING_LANGUAGE_MAP.getOrDefault(Locale.getDefault().getLanguage(), EN);
}

View File

@@ -35,17 +35,6 @@ public interface Translator {
*/
String translate(String text, Language to);
/**
* Translates the given text to the given language
*
* @param text The text to translate
* @param to The target language
* @return The translated text
*/
default String translate(final String text, final String to) {
return translate(text, Language.getLanguage(to));
}
/**
* Translates the given subtitle to the given language
*
@@ -55,28 +44,6 @@ public interface Translator {
*/
Subtitle translate(Subtitle subtitle, Language to);
/**
* Translates the given subtitle to the given language
*
* @param subtitle The subtitle to translate
* @param to The target language
* @return The translated subtitle
*/
default Subtitle translate(final Subtitle subtitle, final String to) {
return translate(subtitle, Language.getLanguage(to));
}
/**
* Translates the given subtitles collection to the given language
*
* @param collection The subtitles collection to translate
* @param to The target language
* @return The translated subtitles collection
*/
default SubtitleCollection translate(final SubtitleCollection collection, final String to) {
return translate(collection, Language.getLanguage(to));
}
/**
* Translates the given subtitles collection to the given language
*

View File

@@ -6,15 +6,57 @@ import java.io.IOException;
import java.nio.file.Path;
import java.util.Collection;
/**
* Operates on videos
*/
public interface VideoConverter {
/**
* Adds soft subtitles to the given video
*
* @param video The video
* @param subtitles The subtitles collections to add
* @return The modified video
* @throws IOException If an I/O error occurs
*/
Video addSoftSubtitles(final Video video, final Collection<SubtitleCollection> subtitles) throws IOException;
/**
* Adds soft subtitles to the given video
*
* @param video The video
* @param subtitles The subtitles collections to add
* @param path The output path
* @throws IOException If an I/O error occurs
*/
void addSoftSubtitles(final Video video, final Collection<SubtitleCollection> subtitles, final Path path) throws IOException;
/**
* Adds hard subtitles to the given video
*
* @param video The video
* @param subtitles The subtitle collection to add
* @return The modified video
* @throws IOException If an I/O error occurs
*/
Video addHardSubtitles(final Video video, final SubtitleCollection subtitles) throws IOException;
/**
* Adds hard subtitles to the given video
*
* @param video The video
* @param subtitles The subtitle collection to add
* @param path The output path
* @throws IOException If an I/O error occurs
*/
void addHardSubtitles(final Video video, final SubtitleCollection subtitles, final Path path) throws IOException;
/**
* Extracts the audio from the given video
*
* @param video The video
* @return The audio
* @throws IOException If an I/O error occurs
*/
Audio getAudio(final Video video) throws IOException;
}

View File

@@ -19,7 +19,6 @@ public interface VideoInfo {
*/
int height();
/**
* @return The video duration in milliseconds
*/
@@ -29,6 +28,6 @@ public interface VideoInfo {
* @return The aspect ratio of the video
*/
default double aspectRatio() {
return (double) width() / height();
return width() / (double) height();
}
}

View File

@@ -15,7 +15,6 @@ public interface Bounds {
*/
double y();
/**
* @return the width
*/

View File

@@ -0,0 +1,37 @@
package com.github.gtache.autosubtitle;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.api.io.TempDir;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Objects;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)
class TestFile {
private final File file;
TestFile(@Mock final File file) {
this.file = Objects.requireNonNull(file);
}
@Test
void testGetInputStream(@TempDir final Path dir) throws IOException {
final var path = dir.resolve("path");
Files.writeString(path, "test");
when(file.getInputStream()).thenCallRealMethod();
when(file.path()).thenReturn(path);
try (final var in = file.getInputStream()) {
assertEquals("test", new String(in.readAllBytes()));
}
}
}

View File

@@ -0,0 +1,25 @@
package com.github.gtache.autosubtitle;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
class TestLanguage {
@Test
void testLanguage() {
assertEquals("french", Language.FR.englishName());
assertEquals("fr", Language.FR.iso2());
assertEquals("fra", Language.FR.iso3());
assertEquals(Language.FR, Language.getLanguage("fr"));
assertEquals(Language.FR, Language.getLanguage("FR"));
assertEquals(Language.FR, Language.getLanguage("fra"));
assertEquals(Language.FR, Language.getLanguage("FRA"));
assertEquals(Language.FR, Language.getLanguage("french"));
assertEquals(Language.FR, Language.getLanguage("French"));
assertNotNull(Language.getDefault());
}
}

View File

@@ -0,0 +1,37 @@
package com.github.gtache.autosubtitle;
import com.github.gtache.autosubtitle.subtitle.Subtitle;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import java.util.Objects;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)
class TestTranslator {
private final Translator translator;
private final Subtitle subtitle;
TestTranslator(@Mock final Translator translator, @Mock final Subtitle subtitle) {
this.translator = Objects.requireNonNull(translator);
this.subtitle = Objects.requireNonNull(subtitle);
}
@Test
void testGetLanguage() {
when(translator.getLanguage(subtitle)).thenCallRealMethod();
final var text = "text";
when(subtitle.content()).thenReturn(text);
when(translator.getLanguage(text)).thenReturn(Language.FR);
assertEquals(Language.FR, translator.getLanguage(subtitle));
verify(translator).getLanguage(text);
}
}

View File

@@ -0,0 +1,34 @@
package com.github.gtache.autosubtitle;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import java.util.Objects;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)
class TestVideoInfo {
private final VideoInfo videoInfo;
TestVideoInfo(@Mock final VideoInfo videoInfo) {
this.videoInfo = Objects.requireNonNull(videoInfo);
}
@Test
void testAspectRatio() {
when(videoInfo.aspectRatio()).thenCallRealMethod();
final var width = 30;
final var height = 12;
when(videoInfo.width()).thenReturn(width);
when(videoInfo.height()).thenReturn(height);
assertEquals(width / (double) height, videoInfo.aspectRatio());
}
}

View File

@@ -0,0 +1,55 @@
package com.github.gtache.autosubtitle.com.github.gtache.autosubtitle.subtitle;
import com.github.gtache.autosubtitle.subtitle.Subtitle;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import java.time.Duration;
import java.util.Objects;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)
class TestSubtitle {
private final Subtitle subtitle;
TestSubtitle(@Mock final Subtitle subtitle) {
this.subtitle = Objects.requireNonNull(subtitle);
}
@Test
void testDuration() {
when(subtitle.duration()).thenCallRealMethod();
final var start = 1000L;
final var end = 5000L;
when(subtitle.start()).thenReturn(start);
when(subtitle.end()).thenReturn(end);
final var expected = Duration.ofMillis(end - start);
assertEquals(expected, subtitle.duration());
}
@Test
void testIsShowing() {
when(subtitle.isShowing(anyLong())).thenCallRealMethod();
final var start = 1000L;
final var end = 5000L;
when(subtitle.start()).thenReturn(start);
when(subtitle.end()).thenReturn(end);
assertFalse(subtitle.isShowing(999L));
assertTrue(subtitle.isShowing(1000L));
assertTrue(subtitle.isShowing(3000L));
assertTrue(subtitle.isShowing(5000L));
assertFalse(subtitle.isShowing(5001L));
}
}

View File

@@ -0,0 +1,64 @@
package com.github.gtache.autosubtitle.com.github.gtache.autosubtitle.subtitle.converter;
import com.github.gtache.autosubtitle.subtitle.SubtitleCollection;
import com.github.gtache.autosubtitle.subtitle.converter.ParseException;
import com.github.gtache.autosubtitle.subtitle.converter.SubtitleConverter;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.api.io.TempDir;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Objects;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)
class TestSubtitleConverter {
private final SubtitleConverter subtitleConverter;
private final SubtitleCollection subtitleCollection;
TestSubtitleConverter(@Mock final SubtitleConverter subtitleConverter,
@Mock final SubtitleCollection subtitleCollection) {
this.subtitleConverter = Objects.requireNonNull(subtitleConverter);
this.subtitleCollection = Objects.requireNonNull(subtitleCollection);
}
@Test
void testParse(@TempDir final Path tempDir) throws ParseException, IOException {
final var file = tempDir.resolve("test.srt");
final var string = "test";
Files.writeString(file, string);
when(subtitleConverter.parse(file)).thenCallRealMethod();
when(subtitleConverter.parse(string)).thenReturn(subtitleCollection);
assertEquals(subtitleCollection, subtitleConverter.parse(file));
}
@Test
void testParseException(@TempDir final Path tempDir) throws ParseException {
final var file = tempDir.resolve("test.srt");
when(subtitleConverter.parse(file)).thenCallRealMethod();
when(subtitleConverter.parse(anyString())).thenReturn(subtitleCollection);
assertThrows(ParseException.class, () -> subtitleConverter.parse(file));
}
@Test
void testCanParse(@TempDir final Path tempDir) {
final var file = tempDir.resolve("test.srt");
final var otherFile = tempDir.resolve("other.ass");
when(subtitleConverter.formatName()).thenReturn("srt");
when(subtitleConverter.canParse(any())).thenCallRealMethod();
assertTrue(subtitleConverter.canParse(file));
assertFalse(subtitleConverter.canParse(otherFile));
}
}

View File

@@ -0,0 +1,57 @@
package com.github.gtache.autosubtitle.com.github.gtache.autosubtitle.subtitle.extractor;
import com.github.gtache.autosubtitle.Audio;
import com.github.gtache.autosubtitle.Language;
import com.github.gtache.autosubtitle.Video;
import com.github.gtache.autosubtitle.subtitle.SubtitleCollection;
import com.github.gtache.autosubtitle.subtitle.extractor.ExtractException;
import com.github.gtache.autosubtitle.subtitle.extractor.ExtractionModel;
import com.github.gtache.autosubtitle.subtitle.extractor.SubtitleExtractor;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import java.util.Objects;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)
class TestSubtitleExtractor {
private final SubtitleExtractor subtitleExtractor;
private final SubtitleCollection subtitleCollection;
private final Audio audio;
private final Video video;
private final ExtractionModel extractionModel;
TestSubtitleExtractor(@Mock final SubtitleExtractor subtitleExtractor,
@Mock final SubtitleCollection subtitleCollection,
@Mock final Audio audio,
@Mock final Video video,
@Mock final ExtractionModel extractionModel) {
this.subtitleExtractor = Objects.requireNonNull(subtitleExtractor);
this.subtitleCollection = Objects.requireNonNull(subtitleCollection);
this.audio = Objects.requireNonNull(audio);
this.video = Objects.requireNonNull(video);
this.extractionModel = Objects.requireNonNull(extractionModel);
}
@Test
void testExtractVideo() throws ExtractException {
when(subtitleExtractor.extract(any(Video.class), any())).thenCallRealMethod();
when(subtitleExtractor.extract(video, Language.AUTO, extractionModel)).thenReturn(subtitleCollection);
assertEquals(subtitleCollection, subtitleExtractor.extract(video, extractionModel));
}
@Test
void testExtractAudio() throws ExtractException {
when(subtitleExtractor.extract(any(Audio.class), any())).thenCallRealMethod();
when(subtitleExtractor.extract(audio, Language.AUTO, extractionModel)).thenReturn(subtitleCollection);
assertEquals(subtitleCollection, subtitleExtractor.extract(audio, extractionModel));
}
}

View File

@@ -0,0 +1,56 @@
package com.github.gtache.autosubtitle.process;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import java.io.IOException;
import java.util.List;
import java.util.Objects;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)
class TestProcessRunner {
private final ProcessRunner processRunner;
private final ProcessResult result;
private final Process process;
private final ProcessListener processListener;
TestProcessRunner(@Mock final ProcessRunner processRunner, @Mock final ProcessResult result,
@Mock final Process process, @Mock final ProcessListener processListener) {
this.processRunner = Objects.requireNonNull(processRunner);
this.result = Objects.requireNonNull(result);
this.process = Objects.requireNonNull(process);
this.processListener = Objects.requireNonNull(processListener);
}
@Test
void testRunVarargs() throws IOException {
when(processRunner.run(List.of("arg1", "arg2"))).thenReturn(result);
when(processRunner.run(any(String[].class))).thenCallRealMethod();
assertEquals(result, processRunner.run("arg1", "arg2"));
}
@Test
void testStartVarargs() throws IOException {
when(processRunner.start(List.of("arg1", "arg2"))).thenReturn(process);
when(processRunner.start(any(String[].class))).thenCallRealMethod();
assertEquals(process, processRunner.start("arg1", "arg2"));
}
@Test
void testStartListenVarargs() throws IOException {
when(processRunner.startListen(List.of("arg1", "arg2"))).thenReturn(processListener);
when(processRunner.startListen(any(String[].class))).thenCallRealMethod();
assertEquals(processListener, processRunner.startListen("arg1", "arg2"));
}
}

View File

@@ -0,0 +1,18 @@
package com.github.gtache.autosubtitle.setup;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
class TestSetupStatus {
@Test
void testIsInstalled() {
assertFalse(SetupStatus.ERRORED.isInstalled());
assertFalse(SetupStatus.NOT_INSTALLED.isInstalled());
assertTrue(SetupStatus.SYSTEM_INSTALLED.isInstalled());
assertTrue(SetupStatus.BUNDLE_INSTALLED.isInstalled());
assertTrue(SetupStatus.UPDATE_AVAILABLE.isInstalled());
}
}