Adds tests for core

This commit is contained in:
Guillaume Tâche
2024-08-10 21:42:14 +02:00
parent 428edcd806
commit 7bddf53bab
30 changed files with 1265 additions and 13 deletions

View File

@@ -1,7 +1,7 @@
package com.github.gtache.autosubtitle.impl; package com.github.gtache.autosubtitle.impl;
/** /**
* The list of possible operating systems * The list of possible CPU architectures
*/ */
public enum Architecture { public enum Architecture {
//32 bit //32 bit
@@ -16,6 +16,12 @@ public enum Architecture {
ARM64, ARMV8, ARMV9, AARCH64, ARM64, ARMV8, ARMV9, AARCH64,
UNKNOWN; UNKNOWN;
/**
* Returns the architecture for the given name
*
* @param name The name
* @return The architecture, or UNKNOWN if not found
*/
public static Architecture getArchitecture(final String name) { public static Architecture getArchitecture(final String name) {
try { try {
return valueOf(name.toUpperCase()); return valueOf(name.toUpperCase());
@@ -24,10 +30,25 @@ public enum Architecture {
} }
} }
/**
* Returns the architecture for the current system
*
* @return The architecture, or UNKNOWN if not found
*/
public static Architecture getArchitecture() {
return getArchitecture(System.getProperty("os.arch"));
}
/**
* @return true if the architecture is AMD/Intel 64 bit
*/
public boolean isAMD64() { public boolean isAMD64() {
return this == X86 || this == X86_64 || this == AMD64; return this == X86 || this == X86_64 || this == AMD64;
} }
/**
* @return true if the architecture is ARM 64 bit
*/
public boolean isARM64() { public boolean isARM64() {
return this == ARM64 || this == ARMV8 || this == ARMV9 || this == AARCH64; return this == ARM64 || this == ARMV8 || this == ARMV9 || this == AARCH64;
} }

View File

@@ -0,0 +1,18 @@
package com.github.gtache.autosubtitle.impl;
/**
* Thrown when an error occurs during dependency injection
*/
public class DaggerException extends RuntimeException {
public DaggerException(final String message) {
super(message);
}
public DaggerException(final String message, final Throwable cause) {
super(message, cause);
}
public DaggerException(final Throwable cause) {
super(cause);
}
}

View File

@@ -4,5 +4,18 @@ package com.github.gtache.autosubtitle.impl;
* The list of possible operating systems * The list of possible operating systems
*/ */
public enum OS { public enum OS {
WINDOWS, LINUX, MAC WINDOWS, LINUX, MAC, UNKNOWN;
public static OS getOS() {
final var name = System.getProperty("os.name");
if (name.contains("Windows")) {
return WINDOWS;
} else if (name.contains("Mac")) {
return MAC;
} else if (name.contains("inux") || name.contains("unix")) {
return LINUX;
} else {
return UNKNOWN;
}
}
} }

View File

@@ -1,6 +1,7 @@
package com.github.gtache.autosubtitle.modules.impl; package com.github.gtache.autosubtitle.modules.impl;
import com.github.gtache.autosubtitle.impl.Architecture; import com.github.gtache.autosubtitle.impl.Architecture;
import com.github.gtache.autosubtitle.impl.DaggerException;
import com.github.gtache.autosubtitle.impl.OS; import com.github.gtache.autosubtitle.impl.OS;
import com.github.gtache.autosubtitle.modules.setup.impl.SetupModule; import com.github.gtache.autosubtitle.modules.setup.impl.SetupModule;
import com.github.gtache.autosubtitle.modules.subtitle.impl.SubtitleModule; import com.github.gtache.autosubtitle.modules.subtitle.impl.SubtitleModule;
@@ -19,20 +20,22 @@ public final class CoreModule {
@Provides @Provides
static OS providesOS() { static OS providesOS() {
final var name = System.getProperty("os.name"); final var os = OS.getOS();
if (name.contains("Windows")) { if (os == OS.UNKNOWN) {
return OS.WINDOWS; throw new DaggerException("Unsupported OS: " + System.getProperty("os.name"));
} else if (name.contains("Mac")) {
return OS.MAC;
} else { } else {
return OS.LINUX; return os;
} }
} }
@Provides @Provides
static Architecture providesArchitecture() { static Architecture providesArchitecture() {
final var arch = System.getProperty("os.arch"); final var architecture = Architecture.getArchitecture();
return Architecture.getArchitecture(arch); if (architecture == Architecture.UNKNOWN) {
throw new DaggerException("Unsupported architecture: " + System.getProperty("os.arch"));
} else {
return architecture;
}
} }
@Provides @Provides

View File

@@ -8,6 +8,9 @@ import java.lang.annotation.Target;
import static java.lang.annotation.RetentionPolicy.RUNTIME; import static java.lang.annotation.RetentionPolicy.RUNTIME;
/**
* The extension of an executable for the current OS
*/
@Qualifier @Qualifier
@Documented @Documented
@Retention(RUNTIME) @Retention(RUNTIME)

View File

@@ -58,6 +58,10 @@ public class ProcessListenerImpl implements ProcessListener {
if (process.isAlive()) { if (process.isAlive()) {
process.destroyForcibly(); process.destroyForcibly();
} }
//Reads lines to output
while (readLine() != null) {
//Do nothing
}
reader.close(); reader.close();
return new ProcessResultImpl(process.exitValue(), output); return new ProcessResultImpl(process.exitValue(), output);
} }

View File

@@ -10,6 +10,9 @@ import java.util.List;
public record ProcessResultImpl(int exitCode, List<String> output) implements ProcessResult { public record ProcessResultImpl(int exitCode, List<String> output) implements ProcessResult {
public ProcessResultImpl { public ProcessResultImpl {
if (exitCode < 0) {
throw new IllegalArgumentException("Exit code must be >= 0 : " + exitCode);
}
output = List.copyOf(output); output = List.copyOf(output);
} }
} }

View File

@@ -37,7 +37,7 @@ public class SRTSubtitleConverter implements SubtitleConverter {
return (i + 1) + "\n" + return (i + 1) + "\n" +
formatTime(subtitle.start()) + " --> " + formatTime(subtitle.end()) + "\n" + formatTime(subtitle.start()) + " --> " + formatTime(subtitle.end()) + "\n" +
subtitle.content(); subtitle.content();
}).collect(Collectors.joining("\n\n")); }).collect(Collectors.joining("\n\n")) + "\n";
} }
private static String formatTime(final long time) { private static String formatTime(final long time) {
@@ -62,11 +62,11 @@ public class SRTSubtitleConverter implements SubtitleConverter {
final var endTimeStr = timeSplit[1]; final var endTimeStr = timeSplit[1];
final var start = parseTime(startTimeStr); final var start = parseTime(startTimeStr);
final var end = parseTime(endTimeStr); final var end = parseTime(endTimeStr);
final var text = String.join(" ", Arrays.stream(lines).skip(2).toList()); final var text = String.join("\n", Arrays.stream(lines).skip(2).toList());
return new SubtitleImpl(text, start, end, null, null); return new SubtitleImpl(text, start, end, null, null);
}).toList(); }).toList();
final var text = subtitles.stream().map(Subtitle::content).collect(Collectors.joining(" ")); final var text = subtitles.stream().map(Subtitle::content).collect(Collectors.joining(" "));
return new SubtitleCollectionImpl(content, subtitles, translator.getLanguage(text)); return new SubtitleCollectionImpl(text, subtitles, translator.getLanguage(text));
} catch (final Exception e) { } catch (final Exception e) {
throw new ParseException(e); throw new ParseException(e);
} }

View File

@@ -0,0 +1,58 @@
package com.github.gtache.autosubtitle.impl;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.util.Arrays;
import java.util.Set;
import static com.github.gtache.autosubtitle.impl.Architecture.*;
import static org.junit.jupiter.api.Assertions.*;
class TestArchitecture {
private static final String ARCHITECTURE = System.getProperty("os.arch");
@BeforeEach
void beforeEach() {
System.setProperty("os.arch", ARCHITECTURE);
}
@AfterEach
void afterEach() {
System.setProperty("os.arch", ARCHITECTURE);
}
@Test
void testGetArchitecture() {
for (final var value : Architecture.values()) {
System.setProperty("os.arch", value.name());
assertEquals(value, Architecture.getArchitecture());
}
System.setProperty("os.arch", "any");
assertEquals(UNKNOWN, Architecture.getArchitecture());
}
@Test
void testGetArchitectureName() {
assertEquals(I386, Architecture.getArchitecture("i386"));
assertEquals(I386, Architecture.getArchitecture("I386"));
}
@Test
void testIsAMD64() {
final var expectedAMD64 = Set.of(X86, X86_64, AMD64);
expectedAMD64.forEach(a -> assertTrue(a.isAMD64()));
Arrays.stream(Architecture.values()).filter(a -> !expectedAMD64.contains(a))
.forEach(a -> assertFalse(a.isAMD64()));
}
@Test
void testIsARM64() {
final var expectedARM64 = Set.of(ARM64, ARMV8, ARMV9, AARCH64);
expectedARM64.forEach(a -> assertTrue(a.isARM64()));
Arrays.stream(Architecture.values()).filter(a -> !expectedARM64.contains(a))
.forEach(a -> assertFalse(a.isARM64()));
}
}

View File

@@ -0,0 +1,30 @@
package com.github.gtache.autosubtitle.impl;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
class TestAudioInfoImpl {
private final String audioFormat;
private final long duration;
TestAudioInfoImpl() {
this.audioFormat = "audioFormat";
this.duration = 1000L;
}
@Test
void testGetters() {
final var audioInfo = new AudioInfoImpl(audioFormat, duration);
assertEquals(audioFormat, audioInfo.audioFormat());
assertEquals(duration, audioInfo.duration());
}
@Test
void testIllegal() {
assertThrows(NullPointerException.class, () -> new AudioInfoImpl(null, duration));
assertThrows(IllegalArgumentException.class, () -> new AudioInfoImpl(audioFormat, -1));
}
}

View File

@@ -0,0 +1,50 @@
package com.github.gtache.autosubtitle.impl;
import com.github.gtache.autosubtitle.AudioInfo;
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 static java.util.Objects.requireNonNull;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
@ExtendWith(MockitoExtension.class)
class TestFileAudioImpl {
private final Path path;
private final AudioInfo info;
TestFileAudioImpl(@Mock final Path path, @Mock final AudioInfo info) throws IOException {
this.path = requireNonNull(path);
this.info = requireNonNull(info);
}
@Test
void testGetters() {
final var fileAudio = new FileAudioImpl(path, info);
assertEquals(path, fileAudio.path());
assertEquals(info, fileAudio.info());
}
@Test
void testGetInputStream(@TempDir final Path dir) throws IOException {
final var content = "test";
final var filepath = dir.resolve("path");
Files.writeString(filepath, content);
final var fileAudio = new FileAudioImpl(filepath, info);
assertEquals(content, new String(fileAudio.getInputStream().readAllBytes()));
}
@Test
void testIllegal() {
assertThrows(NullPointerException.class, () -> new FileAudioImpl(null, info));
assertThrows(NullPointerException.class, () -> new FileAudioImpl(path, null));
}
}

View File

@@ -0,0 +1,51 @@
package com.github.gtache.autosubtitle.impl;
import com.github.gtache.autosubtitle.VideoInfo;
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 static java.util.Objects.requireNonNull;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
@ExtendWith(MockitoExtension.class)
class TestFileVideoImpl {
private final Path path;
private final VideoInfo info;
TestFileVideoImpl(@Mock final Path path, @Mock final VideoInfo info) {
this.path = requireNonNull(path);
this.info = requireNonNull(info);
}
@Test
void testGetters() {
final var fileVideo = new FileVideoImpl(path, info);
assertEquals(path, fileVideo.path());
assertEquals(info, fileVideo.info());
}
@Test
void testGetInputStream(@TempDir final Path dir) throws IOException {
final var content = "test";
final var filepath = dir.resolve("path");
Files.writeString(filepath, content);
final var fileVideo = new FileVideoImpl(filepath, info);
assertEquals(content, new String(fileVideo.getInputStream().readAllBytes()));
}
@Test
void testIllegal() {
assertThrows(NullPointerException.class, () -> new FileVideoImpl(null, info));
assertThrows(NullPointerException.class, () -> new FileVideoImpl(path, null));
}
}

View File

@@ -0,0 +1,41 @@
package com.github.gtache.autosubtitle.impl;
import com.github.gtache.autosubtitle.AudioInfo;
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.InputStream;
import java.util.function.Supplier;
import static java.util.Objects.requireNonNull;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
@ExtendWith(MockitoExtension.class)
class TestMemoryAudioImpl {
private final Supplier<InputStream> supplier;
private final AudioInfo info;
TestMemoryAudioImpl(@Mock InputStream inputStream, @Mock AudioInfo info) {
this.supplier = () -> requireNonNull(inputStream);
this.info = requireNonNull(info);
}
@Test
void testGetters() {
final var audio = new MemoryAudioImpl(supplier, info);
assertEquals(supplier, audio.inputStreamSupplier());
assertEquals(supplier.get(), audio.getInputStream());
assertEquals(info, audio.info());
}
@Test
void testIllegal() {
assertThrows(NullPointerException.class, () -> new MemoryAudioImpl(null, info));
assertThrows(NullPointerException.class, () -> new MemoryAudioImpl(supplier, null));
}
}

View File

@@ -0,0 +1,40 @@
package com.github.gtache.autosubtitle.impl;
import com.github.gtache.autosubtitle.VideoInfo;
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.InputStream;
import java.util.function.Supplier;
import static java.util.Objects.requireNonNull;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
@ExtendWith(MockitoExtension.class)
class TestMemoryVideoImpl {
private final Supplier<InputStream> supplier;
private final VideoInfo info;
TestMemoryVideoImpl(@Mock InputStream inputStream, @Mock VideoInfo info) {
this.supplier = () -> requireNonNull(inputStream);
this.info = requireNonNull(info);
}
@Test
void testGetters() {
final var video = new MemoryVideoImpl(supplier, info);
assertEquals(supplier, video.inputStreamSupplier());
assertEquals(supplier.get(), video.getInputStream());
assertEquals(info, video.info());
}
@Test
void testIllegal() {
assertThrows(NullPointerException.class, () -> new MemoryVideoImpl(null, info));
assertThrows(NullPointerException.class, () -> new MemoryVideoImpl(supplier, null));
}
}

View File

@@ -0,0 +1,33 @@
package com.github.gtache.autosubtitle.impl;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.util.stream.Stream;
import static org.junit.jupiter.api.Assertions.assertEquals;
class TestOS {
private static final String OS_NAME = System.getProperty("os.name");
@BeforeEach
void beforeEach() {
System.setProperty("os.name", OS_NAME);
}
@AfterEach
void afterEach() {
System.setProperty("os.name", OS_NAME);
}
@Test
void testGetOS() {
Stream.of("Windows", "Mac", "Linux").forEach(s -> {
System.setProperty("os.name", s);
assertEquals(OS.valueOf(s.toUpperCase()), OS.getOS());
});
System.setProperty("os.name", "Solaris");
assertEquals(OS.UNKNOWN, OS.getOS());
}
}

View File

@@ -0,0 +1,38 @@
package com.github.gtache.autosubtitle.impl;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
class TestVideoInfoImpl {
private final String videoFormat;
private final int width;
private final int height;
private final long duration;
TestVideoInfoImpl() {
this.videoFormat = "videoFormat";
this.width = 1;
this.height = 2;
this.duration = 3;
}
@Test
void testGetters() {
final var videoInfo = new VideoInfoImpl(videoFormat, width, height, duration);
assertEquals(videoFormat, videoInfo.videoFormat());
assertEquals(width, videoInfo.width());
assertEquals(height, videoInfo.height());
assertEquals(duration, videoInfo.duration());
}
@Test
void testIllegal() {
assertThrows(NullPointerException.class, () -> new VideoInfoImpl(null, width, height, duration));
assertThrows(IllegalArgumentException.class, () -> new VideoInfoImpl(videoFormat, 0, height, duration));
assertThrows(IllegalArgumentException.class, () -> new VideoInfoImpl(videoFormat, width, 0, duration));
assertThrows(IllegalArgumentException.class, () -> new VideoInfoImpl(videoFormat, width, height, 0));
}
}

View File

@@ -0,0 +1,60 @@
package com.github.gtache.autosubtitle.modules.impl;
import com.github.gtache.autosubtitle.impl.Architecture;
import com.github.gtache.autosubtitle.impl.DaggerException;
import com.github.gtache.autosubtitle.impl.OS;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.util.stream.Stream;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
class TestCoreModule {
private static final String OS_NAME = System.getProperty("os.name");
private static final String ARCHITECTURE = System.getProperty("os.arch");
@BeforeEach
void beforeEach() {
System.setProperty("os.name", OS_NAME);
System.setProperty("os.arch", ARCHITECTURE);
}
@AfterEach
void afterEach() {
System.setProperty("os.name", OS_NAME);
System.setProperty("os.arch", ARCHITECTURE);
}
@Test
void testProvidesOS() {
Stream.of("Windows", "Mac", "Linux").forEach(s -> {
System.setProperty("os.name", s);
assertEquals(OS.valueOf(s.toUpperCase()), CoreModule.providesOS());
});
System.setProperty("os.name", "Solaris");
assertThrows(DaggerException.class, CoreModule::providesOS);
}
@Test
void testProvidesArchitecture() {
for (final var value : Architecture.values()) {
if (value != Architecture.UNKNOWN) {
System.setProperty("os.arch", value.name());
assertEquals(value, CoreModule.providesArchitecture());
}
}
System.setProperty("os.arch", "any");
assertThrows(DaggerException.class, CoreModule::providesArchitecture);
}
@Test
void testProvidesExecutableExtension() {
assertEquals(".exe", CoreModule.providesExecutableExtension(OS.WINDOWS));
assertEquals("", CoreModule.providesExecutableExtension(OS.MAC));
assertEquals("", CoreModule.providesExecutableExtension(OS.LINUX));
}
}

View File

@@ -0,0 +1,15 @@
package com.github.gtache.autosubtitle.modules.setup.impl;
import org.junit.jupiter.api.Test;
import java.net.http.HttpClient;
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
class TestSetupModule {
@Test
void testHttpClient() {
assertInstanceOf(HttpClient.class, SetupModule.providesHttpClient());
}
}

View File

@@ -0,0 +1,61 @@
package com.github.gtache.autosubtitle.process.impl;
import com.github.gtache.autosubtitle.impl.OS;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.time.Duration;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
class TestAbstractProcessRunner {
private static final List<String> ARGS = OS.getOS() == OS.WINDOWS ? List.of("powershell.exe", "-Command", "\"echo '1\n2\n3'\"") : List.of("echo", "1\n2\n3");
private final DummyProcessRunner dummyProcessRunner;
TestAbstractProcessRunner() {
this.dummyProcessRunner = new DummyProcessRunner();
}
@Test
void testRun() throws IOException {
final var expected = new ProcessResultImpl(0, List.of("1", "2", "3"));
final var actual = dummyProcessRunner.run(ARGS);
assertEquals(expected, actual);
}
@Test
void testStart() throws IOException, InterruptedException {
final var process = dummyProcessRunner.start(ARGS);
process.waitFor();
assertEquals(0, process.exitValue());
final var read = new String(process.getInputStream().readAllBytes());
final var expected = OS.getOS() == OS.WINDOWS ? "1\n2\n3\r\n" : "1\n2\n3\n";
assertEquals(expected, read);
}
@Test
void testStartListen() throws IOException {
final var listener = dummyProcessRunner.startListen(ARGS);
assertEquals("1", listener.readLine());
assertEquals("2", listener.readLine());
assertEquals("3", listener.readLine());
assertNull(listener.readLine());
final var result = listener.join(Duration.ofHours(1));
assertEquals(0, result.exitCode());
assertEquals(List.of("1", "2", "3"), result.output());
}
@Test
void testRunListen() throws IOException {
final var result = dummyProcessRunner.runListen(ARGS);
assertEquals(0, result.exitCode());
assertEquals(List.of("1", "2", "3"), result.output());
}
private static final class DummyProcessRunner extends AbstractProcessRunner {
}
}

View File

@@ -0,0 +1,57 @@
package com.github.gtache.autosubtitle.process.impl;
import com.github.gtache.autosubtitle.process.ProcessListener;
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.ByteArrayInputStream;
import java.io.IOException;
import java.time.Duration;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)
class TestProcessListenerImpl {
private final Process process;
private final ProcessListener listener;
TestProcessListenerImpl(@Mock Process process) {
final var inputStream = new ByteArrayInputStream("line1\nline2\nline3".getBytes());
this.process = Objects.requireNonNull(process);
when(process.getInputStream()).thenReturn(inputStream);
this.listener = new ProcessListenerImpl(process);
}
@Test
void testGetter() {
assertEquals(process, listener.process());
}
@Test
void testReadLine() throws IOException {
assertEquals("line1", listener.readLine());
assertEquals("line2", listener.readLine());
assertEquals("line3", listener.readLine());
assertNull(listener.readLine());
}
@Test
void testJoinAfterRead() throws IOException, InterruptedException {
assertEquals("line1", listener.readLine());
assertEquals("line2", listener.readLine());
final var expectedOutput = List.of("line1", "line2", "line3");
final var expected = new ProcessResultImpl(0, expectedOutput);
final var actual = listener.join(Duration.ofSeconds(1));
verify(process).waitFor(1, TimeUnit.SECONDS);
assertEquals(expected, actual);
assertThrows(IOException.class, listener::readLine);
}
}

View File

@@ -0,0 +1,32 @@
package com.github.gtache.autosubtitle.process.impl;
import org.junit.jupiter.api.Test;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
class TestProcessResultImpl {
private final int exitCode;
private final List<String> output;
TestProcessResultImpl() {
this.exitCode = 0;
this.output = List.of("test");
}
@Test
void testGetters() {
final var result = new ProcessResultImpl(exitCode, output);
assertEquals(exitCode, result.exitCode());
assertEquals(output, result.output());
}
@Test
void testIllegal() {
assertThrows(IllegalArgumentException.class, () -> new ProcessResultImpl(-1, output));
assertThrows(NullPointerException.class, () -> new ProcessResultImpl(exitCode, null));
}
}

View File

@@ -0,0 +1,257 @@
package com.github.gtache.autosubtitle.setup.impl;
import com.github.gtache.autosubtitle.setup.SetupAction;
import com.github.gtache.autosubtitle.setup.SetupEvent;
import com.github.gtache.autosubtitle.setup.SetupException;
import com.github.gtache.autosubtitle.setup.SetupListener;
import com.github.gtache.autosubtitle.setup.SetupStatus;
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.net.http.HttpClient;
import java.net.http.HttpResponse;
import java.nio.file.Files;
import java.nio.file.Path;
import static java.util.Objects.requireNonNull;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;
@ExtendWith(MockitoExtension.class)
class TestAbstractSetupManager {
private final DummySetupManager manager;
private final SetupListener listener1;
private final SetupListener listener2;
private final SetupEvent event;
private final SetupAction setupAction;
private final HttpClient httpClient;
TestAbstractSetupManager(@Mock final SetupListener listener1,
@Mock final SetupListener listener2,
@Mock final SetupEvent event,
@Mock final SetupAction setupAction,
@Mock final HttpClient httpClient) {
this.manager = spy(new DummySetupManager(httpClient));
this.listener1 = requireNonNull(listener1);
this.listener2 = requireNonNull(listener2);
this.event = requireNonNull(event);
this.setupAction = requireNonNull(setupAction);
this.httpClient = requireNonNull(httpClient);
}
@Test
void testRemoveListenerStart() {
manager.addListener(listener1);
manager.addListener(listener2);
manager.removeListener(listener2);
manager.sendStartEvent(event);
verify(listener1).onActionStart(event);
verifyNoInteractions(listener2);
}
@Test
void testRemoveListenerEnd() {
manager.addListener(listener1);
manager.addListener(listener2);
manager.removeListener(listener2);
manager.sendEndEvent(event);
verify(listener1).onActionEnd(event);
verifyNoInteractions(listener2);
}
@Test
void testRemoveListenersStart() {
manager.addListener(listener1);
manager.addListener(listener2);
manager.removeListeners();
manager.sendStartEvent(event);
verifyNoInteractions(listener1, listener2);
}
@Test
void testRemoveListenersEnd() {
manager.addListener(listener1);
manager.addListener(listener2);
manager.removeListeners();
manager.sendEndEvent(event);
verifyNoInteractions(listener1, listener2);
}
@Test
void testReinstall() throws SetupException {
manager.reinstall();
final var inOrder = inOrder(manager);
final var name = manager.name();
inOrder.verify(manager).sendStartEvent(SetupAction.UNINSTALL, name, 0);
inOrder.verify(manager).uninstall();
inOrder.verify(manager).sendEndEvent(SetupAction.UNINSTALL, name, -1);
inOrder.verify(manager).sendStartEvent(SetupAction.INSTALL, name, -1);
inOrder.verify(manager).install();
inOrder.verify(manager).sendEndEvent(SetupAction.INSTALL, name, 1);
}
@Test
void testIsUpdateAvailable() throws SetupException {
doReturn(SetupStatus.UPDATE_AVAILABLE).when(manager).getStatus();
assertTrue(manager.isUpdateAvailable());
doReturn(SetupStatus.ERRORED).when(manager).getStatus();
assertFalse(manager.isUpdateAvailable());
doReturn(SetupStatus.NOT_INSTALLED).when(manager).getStatus();
assertFalse(manager.isUpdateAvailable());
doReturn(SetupStatus.SYSTEM_INSTALLED).when(manager).getStatus();
assertFalse(manager.isUpdateAvailable());
doReturn(SetupStatus.BUNDLE_INSTALLED).when(manager).getStatus();
assertFalse(manager.isUpdateAvailable());
}
@Test
void testIsInstalled() throws SetupException {
doReturn(SetupStatus.SYSTEM_INSTALLED).when(manager).getStatus();
assertTrue(manager.isInstalled());
doReturn(SetupStatus.BUNDLE_INSTALLED).when(manager).getStatus();
assertTrue(manager.isInstalled());
doReturn(SetupStatus.UPDATE_AVAILABLE).when(manager).getStatus();
assertTrue(manager.isInstalled());
doReturn(SetupStatus.ERRORED).when(manager).getStatus();
assertFalse(manager.isInstalled());
doReturn(SetupStatus.NOT_INSTALLED).when(manager).getStatus();
assertFalse(manager.isInstalled());
}
@Test
void testStatus() throws SetupException {
assertEquals(SetupStatus.SYSTEM_INSTALLED, manager.status());
final var inOrder = inOrder(manager);
final var name = manager.name();
inOrder.verify(manager).sendStartEvent(SetupAction.CHECK, name, 0);
inOrder.verify(manager).getStatus();
inOrder.verify(manager).sendEndEvent(SetupAction.CHECK, name, 1);
}
@Test
void testStatusException() throws SetupException {
doThrow(SetupException.class).when(manager).getStatus();
assertEquals(SetupStatus.ERRORED, manager.status());
final var inOrder = inOrder(manager);
final var name = manager.name();
inOrder.verify(manager).sendStartEvent(SetupAction.CHECK, name, 0);
inOrder.verify(manager).getStatus();
inOrder.verify(manager).sendEndEvent(SetupAction.CHECK, name, 1);
}
@Test
void testSendStartEventParameters() {
final var target = "target";
final var progress = 0.5;
manager.sendStartEvent(setupAction, target, progress);
verify(manager).sendStartEvent(new SetupEventImpl(setupAction, target, progress, manager));
}
@Test
void testSendEndEventParameters() {
final var target = "target";
final var progress = 0.5;
manager.sendEndEvent(setupAction, target, progress);
verify(manager).sendEndEvent(new SetupEventImpl(setupAction, target, progress, manager));
}
@Test
void testDeleteFolder(@TempDir final Path tempDirectory) throws IOException, SetupException {
final var subFolder = tempDirectory.resolve("subFolder");
final var file = tempDirectory.resolve("file.txt");
final var subFile = subFolder.resolve("file.txt");
Files.createDirectories(subFolder);
Files.createFile(file);
Files.createFile(subFile);
manager.deleteFolder(tempDirectory);
assertFalse(Files.exists(tempDirectory));
verify(manager).sendStartEvent(eq(SetupAction.DELETE), anyString(), eq(0.0));
verify(manager).sendStartEvent(eq(SetupAction.DELETE), anyString(), eq(0.25));
verify(manager).sendStartEvent(eq(SetupAction.DELETE), anyString(), eq(0.5));
verify(manager).sendStartEvent(eq(SetupAction.DELETE), anyString(), eq(0.75));
verify(manager).sendEndEvent(eq(SetupAction.DELETE), anyString(), eq(0.25));
verify(manager).sendEndEvent(eq(SetupAction.DELETE), anyString(), eq(0.5));
verify(manager).sendEndEvent(eq(SetupAction.DELETE), anyString(), eq(0.75));
verify(manager).sendEndEvent(eq(SetupAction.DELETE), anyString(), eq(1.0));
}
@Test
void testDownload() throws IOException, InterruptedException, SetupException {
final var url = "http://url";
final var path = mock(Path.class);
final var result = mock(HttpResponse.class);
when(result.statusCode()).thenReturn(200);
when(httpClient.send(any(), any())).thenReturn(result);
manager.download(url, path);
verify(httpClient).send(any(), any());
}
@Test
void testDownloadBadCode() throws IOException, InterruptedException {
final var url = "http://url";
final var path = mock(Path.class);
final var result = mock(HttpResponse.class);
when(result.statusCode()).thenReturn(500);
when(httpClient.send(any(), any())).thenReturn(result);
assertThrows(SetupException.class, () -> manager.download(url, path));
}
@Test
void testDownloadIOException() throws IOException, InterruptedException {
final var url = "http://url";
final var path = mock(Path.class);
when(httpClient.send(any(), any())).thenThrow(IOException.class);
assertThrows(SetupException.class, () -> manager.download(url, path));
}
@Test
void testDownloadInterruptedException() throws IOException, InterruptedException {
final var url = "http://url";
final var path = mock(Path.class);
when(httpClient.send(any(), any())).thenThrow(InterruptedException.class);
assertThrows(SetupException.class, () -> manager.download(url, path));
}
@Test
void testIllegal() {
assertThrows(NullPointerException.class, () -> new DummySetupManager(null));
}
private static final class DummySetupManager extends AbstractSetupManager {
private DummySetupManager(final HttpClient httpClient) {
super(httpClient);
}
@Override
protected SetupStatus getStatus() throws SetupException {
return SetupStatus.SYSTEM_INSTALLED;
}
@Override
public String name() {
return "dummy";
}
@Override
public void install() throws SetupException {
}
@Override
public void uninstall() throws SetupException {
}
@Override
public void update() throws SetupException {
}
}
}

View File

@@ -0,0 +1,45 @@
package com.github.gtache.autosubtitle.setup.impl;
import com.github.gtache.autosubtitle.setup.SetupAction;
import com.github.gtache.autosubtitle.setup.SetupManager;
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.junit.jupiter.api.Assertions.assertThrows;
@ExtendWith(MockitoExtension.class)
class TestSetupEventImpl {
private final SetupAction action;
private final SetupManager setupManager;
private final String target;
private final double progress;
TestSetupEventImpl(@Mock final SetupAction action, @Mock final SetupManager setupManager) {
this.action = Objects.requireNonNull(action);
this.setupManager = Objects.requireNonNull(setupManager);
this.target = "target";
this.progress = 0.5;
}
@Test
void testGetters() {
final var event = new SetupEventImpl(action, target, progress, setupManager);
assertEquals(action, event.action());
assertEquals(target, event.target());
assertEquals(progress, event.progress());
assertEquals(setupManager, event.setupManager());
}
@Test
void testIllegal() {
assertThrows(NullPointerException.class, () -> new SetupEventImpl(null, target, progress, setupManager));
assertThrows(NullPointerException.class, () -> new SetupEventImpl(action, null, progress, setupManager));
assertThrows(NullPointerException.class, () -> new SetupEventImpl(action, target, progress, null));
}
}

View File

@@ -0,0 +1,81 @@
package com.github.gtache.autosubtitle.subtitle.converter.impl;
import com.github.gtache.autosubtitle.Language;
import com.github.gtache.autosubtitle.Translator;
import com.github.gtache.autosubtitle.subtitle.converter.ParseException;
import com.github.gtache.autosubtitle.subtitle.impl.SubtitleCollectionImpl;
import com.github.gtache.autosubtitle.subtitle.impl.SubtitleImpl;
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.Arrays;
import java.util.Objects;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)
class TestSRTSubtitleConverter {
private final Translator translator;
private final Language language;
TestSRTSubtitleConverter(@Mock final Translator translator, @Mock final Language language) {
this.translator = Objects.requireNonNull(translator);
this.language = Objects.requireNonNull(language);
when(translator.getLanguage(anyString())).thenReturn(language);
}
@Test
void testParseFormat() throws ParseException {
final var in = """
1
00:00:00,000 --> 01:02:03,004
test5 test6
test7 test8
2
12:23:34,456 --> 12:23:34,457
test1 test2
test3 test4
""";
final var start1 = 0L;
final var end1 = 60L * 60 * 1000 + 2 * 60 * 1000 + 3 * 1000 + 4;
final var start2 = 12L * 60 * 60 * 1000 + 23 * 60 * 1000 + 34 * 1000 + 456;
final var end2 = 12L * 60 * 60 * 1000 + 23 * 60 * 1000 + 34 * 1000 + 457;
final var subtitle1 = new SubtitleImpl("test5 test6\ntest7 test8", start1, end1, null, null);
final var subtitle2 = new SubtitleImpl("test1 test2\ntest3 test4", start2, end2, null, null);
final var subtitles = new SubtitleCollectionImpl(subtitle1.content() + " " + subtitle2.content(), Arrays.asList(subtitle1, subtitle2), language);
final var converter = new SRTSubtitleConverter(translator);
assertEquals(subtitles, converter.parse(in));
assertEquals(in, converter.format(subtitles));
}
@Test
void testParseException() {
final var in = """
1
121:23:344,456 --> 12:23:34,457
test1 test2
test3 test4
""";
final var converter = new SRTSubtitleConverter(translator);
assertThrows(ParseException.class, () -> converter.parse(in));
}
@Test
void testFormatName() {
final var converter = new SRTSubtitleConverter(translator);
assertEquals("srt", converter.formatName());
}
@Test
void testIllegal() {
assertThrows(NullPointerException.class, () -> new SRTSubtitleConverter(null));
}
}

View File

@@ -0,0 +1,68 @@
package com.github.gtache.autosubtitle.subtitle.extractor.impl;
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.ExtractEvent;
import com.github.gtache.autosubtitle.subtitle.extractor.ExtractException;
import com.github.gtache.autosubtitle.subtitle.extractor.ExtractionModel;
import com.github.gtache.autosubtitle.subtitle.extractor.SubtitleExtractorListener;
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.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoInteractions;
@ExtendWith(MockitoExtension.class)
class TestAbstractSubtitleExtractor {
private final SubtitleExtractorListener listener1;
private final SubtitleExtractorListener listener2;
private final ExtractEvent event;
TestAbstractSubtitleExtractor(@Mock final SubtitleExtractorListener listener1, @Mock final SubtitleExtractorListener listener2,
@Mock final ExtractEvent event) {
this.listener1 = Objects.requireNonNull(listener1);
this.listener2 = Objects.requireNonNull(listener2);
this.event = Objects.requireNonNull(event);
}
@Test
void testRemoveListener() {
final var extractor = new DummySubtitleExtractor();
extractor.addListener(listener1);
extractor.addListener(listener2);
extractor.removeListener(listener2);
extractor.notifyListeners(event);
verify(listener1).listen(event);
verifyNoInteractions(listener2);
}
@Test
void testRemoveListeners() {
final var extractor = new DummySubtitleExtractor();
extractor.addListener(listener1);
extractor.addListener(listener2);
extractor.removeListeners();
extractor.notifyListeners(event);
verifyNoInteractions(listener1, listener2);
}
private static final class DummySubtitleExtractor extends AbstractSubtitleExtractor {
@Override
public SubtitleCollection extract(final Video video, final Language language, final ExtractionModel model) throws ExtractException {
throw new UnsupportedOperationException();
}
@Override
public SubtitleCollection extract(final Audio audio, final Language language, final ExtractionModel model) throws ExtractException {
throw new UnsupportedOperationException();
}
}
}

View File

@@ -0,0 +1,17 @@
package com.github.gtache.autosubtitle.subtitle.extractor.impl;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
class TestExtractEventImpl {
@Test
void testGetters() {
final var message = "test";
final var progress = 0.5;
final var event = new ExtractEventImpl(message, progress);
assertEquals(message, event.message());
assertEquals(progress, event.progress());
}
}

View File

@@ -0,0 +1,30 @@
package com.github.gtache.autosubtitle.subtitle.impl;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
class TestBoundsImpl {
@Test
void testGetters() {
final var x = 1.0;
final var y = 2.0;
final var width = 3.0;
final var height = 4.0;
final var bounds = new BoundsImpl(x, y, width, height);
assertEquals(x, bounds.x());
assertEquals(y, bounds.y());
assertEquals(width, bounds.width());
assertEquals(height, bounds.height());
}
@Test
void testIllegal() {
assertThrows(IllegalArgumentException.class, () -> new BoundsImpl(-1, 0, 0, 0));
assertThrows(IllegalArgumentException.class, () -> new BoundsImpl(0, -1, 0, 0));
assertThrows(IllegalArgumentException.class, () -> new BoundsImpl(0, 0, -1, 0));
assertThrows(IllegalArgumentException.class, () -> new BoundsImpl(0, 0, 0, -1));
}
}

View File

@@ -0,0 +1,30 @@
package com.github.gtache.autosubtitle.subtitle.impl;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
class TestFontImpl {
private final String name;
private final int size;
TestFontImpl() {
this.name = "name";
this.size = 10;
}
@Test
void testGetters() {
final var font = new FontImpl(name, size);
assertEquals(name, font.name());
assertEquals(size, font.size());
}
@Test
void testIllegal() {
assertThrows(NullPointerException.class, () -> new FontImpl(null, size));
assertThrows(IllegalArgumentException.class, () -> new FontImpl(name, 0));
}
}

View File

@@ -0,0 +1,44 @@
package com.github.gtache.autosubtitle.subtitle.impl;
import com.github.gtache.autosubtitle.Language;
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.Collection;
import java.util.List;
import java.util.Objects;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
@ExtendWith(MockitoExtension.class)
class TestSubtitleCollectionImpl {
private final Collection<? extends Subtitle> subtitles;
private final Language langue;
TestSubtitleCollectionImpl(@Mock final Subtitle subtitle, @Mock final Language language) {
this.subtitles = List.of(subtitle);
this.langue = Objects.requireNonNull(language);
}
@Test
void testGetters() {
final var text = "test";
final var collection = new SubtitleCollectionImpl(text, subtitles, langue);
assertEquals(text, collection.text());
assertEquals(subtitles, collection.subtitles());
assertEquals(langue, collection.language());
}
@Test
void testIllegal() {
final var text = "";
assertThrows(NullPointerException.class, () -> new SubtitleCollectionImpl(null, subtitles, langue));
assertThrows(NullPointerException.class, () -> new SubtitleCollectionImpl(text, null, langue));
assertThrows(NullPointerException.class, () -> new SubtitleCollectionImpl(text, subtitles, null));
}
}

View File

@@ -0,0 +1,49 @@
package com.github.gtache.autosubtitle.subtitle.impl;
import com.github.gtache.autosubtitle.subtitle.Bounds;
import com.github.gtache.autosubtitle.subtitle.Font;
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.*;
@ExtendWith(MockitoExtension.class)
class TestSubtitleImpl {
private final Font font;
private final Bounds bounds;
private final long start;
private final long end;
private final String content;
TestSubtitleImpl(@Mock final Font font, @Mock final Bounds bounds) {
this.font = Objects.requireNonNull(font);
this.bounds = Objects.requireNonNull(bounds);
this.start = 1000L;
this.end = 5000L;
this.content = "test";
}
@Test
void testGetters() {
final var subtitle = new SubtitleImpl(content, start, end, font, bounds);
assertEquals(content, subtitle.content());
assertEquals(start, subtitle.start());
assertEquals(end, subtitle.end());
assertEquals(font, subtitle.font());
assertEquals(bounds, subtitle.bounds());
}
@Test
void testIllegal() {
assertThrows(NullPointerException.class, () -> new SubtitleImpl(null, start, end, font, bounds));
assertThrows(IllegalArgumentException.class, () -> new SubtitleImpl(content, -1, end, font, bounds));
assertThrows(IllegalArgumentException.class, () -> new SubtitleImpl(content, start, -1, font, bounds));
assertDoesNotThrow(() -> new SubtitleImpl(content, start, end, null, bounds));
assertDoesNotThrow(() -> new SubtitleImpl(content, start, end, font, null));
}
}