Skip to content

Commit

Permalink
refactor: Divide file save function into 2 parts, add UTs (#641)
Browse files Browse the repository at this point in the history
Signed-off-by: Oleg Kopysov <[email protected]>
  • Loading branch information
o-kopysov authored Oct 22, 2024
1 parent 26d4ae7 commit 68e0ef8
Show file tree
Hide file tree
Showing 7 changed files with 199 additions and 57 deletions.
7 changes: 7 additions & 0 deletions src/main/java/com/lpvs/util/LPVSCommentUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,13 @@
@Slf4j
public class LPVSCommentUtil {

/**
* Private constructor to prevent instantiation of utility class
*/
private LPVSCommentUtil() {
throw new UnsupportedOperationException("Utility class, cannot be instantiated.");
}

/**
* Generates a formatted string containing links to matched lines in a file.
*
Expand Down
132 changes: 80 additions & 52 deletions src/main/java/com/lpvs/util/LPVSFileUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import java.io.FileWriter;
import java.io.BufferedWriter;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
Expand All @@ -33,73 +33,101 @@
@Slf4j
public class LPVSFileUtil {

/**
* Private constructor to prevent instantiation of utility class
*/
private LPVSFileUtil() {
throw new UnsupportedOperationException("Utility class, cannot be instantiated.");
}

/**
* Saves a file with the specified content in a given directory.
*
* @param fileName The name of the file to be saved.
* @param directoryPath The path to the directory where the file will be saved.
* @param patchedLines The content to be written to the file.
* @return {@code true} if file is saved, {@code false} otherwise.
*/
public static void saveFile(String fileName, String directoryPath, List<String> patchedLines) {
try {
if (patchedLines == null || patchedLines.size() == 0) {
log.error("Empty patch for file " + fileName);
return;
public static boolean saveFile(
String fileName, String directoryPath, List<String> patchedLines) {
if (patchedLines == null || patchedLines.isEmpty()) {
log.error("Empty patch for file " + fileName);
return false;
}
int cnt = 1;
StringBuilder prettyPatch = new StringBuilder();
for (String patchedLine : patchedLines) {
// empty line
if (patchedLine.isEmpty()) {
prettyPatch.append("\n");
cnt++;
}
int cnt = 1;
StringBuilder prettyPatch = new StringBuilder();
for (String patchedLine : patchedLines) {
// empty line
if (patchedLine.isEmpty()) {
prettyPatch.append("\n");
cnt++;
}
// added and unchanged lines
else if (patchedLine.charAt(0) == '+' || patchedLine.charAt(0) == ' ') {
prettyPatch.append(patchedLine.substring(1));
// added and unchanged lines
else if (patchedLine.charAt(0) == '+' || patchedLine.charAt(0) == ' ') {
prettyPatch.append(patchedLine.substring(1));
prettyPatch.append("\n");
cnt++;
}
// information(location, number of lines) about changed lines
else if (patchedLine.charAt(0) == '@') {
int fIndex = patchedLine.indexOf("+") + 1;
int lIndex = patchedLine.indexOf(',', fIndex);
if (lIndex == -1) lIndex = patchedLine.indexOf(' ', fIndex);
int startLine = Integer.parseInt(patchedLine.substring(fIndex, lIndex));
log.debug("Line from: " + startLine + " Git string: " + patchedLine);
for (int i = cnt; i < startLine; i++) {
prettyPatch.append("\n");
cnt++;
}
// information(location, number of lines) about changed lines
else if (patchedLine.charAt(0) == '@') {
int fIndex = patchedLine.indexOf("+") + 1;
int lIndex = patchedLine.indexOf(',', fIndex);
if (lIndex == -1) lIndex = patchedLine.indexOf(' ', fIndex);
int startLine = Integer.parseInt(patchedLine.substring(fIndex, lIndex));
log.debug("Line from: " + startLine + " Git string: " + patchedLine);
for (int i = cnt; i < startLine; i++) {
prettyPatch.append("\n");
}
cnt = startLine;
}
cnt = startLine;
}
}

if (fileName.contains("/")) {
String filepath = fileName.substring(0, fileName.lastIndexOf("/"));
Path resultFolder = Paths.get(directoryPath + File.separator + filepath);
if (!Files.exists(resultFolder)) {
try {
// create folder
Files.createDirectories(resultFolder);
log.debug("Folder created successfully.");
} catch (IOException e) {
log.error("Failed to create folder " + resultFolder + e);
}
} else {
log.debug("Folder already exists.");
}
if (!prettyPatch.isEmpty()) {
try {
saveFileToDisk(directoryPath, fileName, prettyPatch.toString());
} catch (IOException e) {
log.error(e.getMessage());
return false;
}
if (prettyPatch.length() > 0) {
try (FileWriter fileWriter =
new FileWriter(
directoryPath + File.separator + fileName,
Charset.forName("UTF8"));
BufferedWriter writer = new BufferedWriter(fileWriter)) {
writer.write(prettyPatch.toString());
}
return true;
}

/**
* Saves the given content to a file with the specified filename in the provided directory.
* @param localDirectoryPath The local directory path where the file should be saved.
* @param fileName The name of the file to be saved.
* @param content The content to be written to the file.
* @throws IOException If there is an error while creating the folder or writing the file.
*/
public static void saveFileToDisk(String localDirectoryPath, String fileName, String content)
throws IOException {
if (fileName.contains("/")) {
String filepath = fileName.substring(0, fileName.lastIndexOf("/"));
Path resultFolder = Paths.get(localDirectoryPath + File.separator + filepath);
if (!Files.exists(resultFolder)) {
try {
// create folder
Files.createDirectories(resultFolder);
log.debug("Folder created successfully.");
} catch (IOException e) {
log.error(e.getMessage());
throw new IOException("Failed to create folder " + resultFolder);
}
} else {
log.debug("Folder already exists.");
}
}

try (FileWriter fileWriter =
new FileWriter(
localDirectoryPath + File.separator + fileName,
StandardCharsets.UTF_8);
BufferedWriter writer = new BufferedWriter(fileWriter)) {
writer.write(content);
} catch (IOException e) {
log.error("Error while writing file " + fileName + ": " + e.getMessage());
log.error(e.getMessage());
throw new IOException("Error while writing file " + fileName);
}
}

Expand Down
7 changes: 7 additions & 0 deletions src/main/java/com/lpvs/util/LPVSPayloadUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@
@Slf4j
public class LPVSPayloadUtil {

/**
* Private constructor to prevent instantiation of utility class
*/
private LPVSPayloadUtil() {
throw new UnsupportedOperationException("Utility class, cannot be instantiated.");
}

/**
* Creates an InputStreamReader object with the specified input stream and UTF-8 encoding.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -740,6 +740,11 @@ public void testGetPathByPullRequest() {
assertNotNull(result);
}

@Test
public void testGetPathByPullRequest_N() {
assertNull(LPVSFileUtil.getPathByPullRequest(null));
}

@Test
public void testRunScan__Scanoss() {
try {
Expand Down
24 changes: 23 additions & 1 deletion src/test/java/com/lpvs/util/LPVSCommentUtilTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;

import static org.junit.jupiter.api.Assertions.assertEquals;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

import static org.junit.jupiter.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.fail;

public class LPVSCommentUtilTest {

Expand Down Expand Up @@ -84,4 +88,22 @@ public void testGetMatchedLinesAsLinkWithNonGitHubVcsMultipleLines() {
+ "9-12 (https://gerrit.org/repo/blob/headCommitSHA/exampleFile.txt#L9L12) ",
result);
}

@Test
void testConstructorThrowsException_N() {
try {
Constructor<LPVSCommentUtil> constructor =
LPVSCommentUtil.class.getDeclaredConstructor();
constructor.setAccessible(true);
constructor.newInstance();
fail("Expected UnsupportedOperationException to be thrown");
} catch (InvocationTargetException e) {
assertInstanceOf(
UnsupportedOperationException.class,
e.getCause(),
"UnsupportedOperationException expected");
} catch (Exception e) {
fail("Unexpected exception type thrown: " + e.getCause());
}
}
}
61 changes: 57 additions & 4 deletions src/test/java/com/lpvs/util/LPVSFileUtilTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,16 @@

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import static com.lpvs.util.LPVSFileUtil.copyFiles;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.*;

public class LPVSFileUtilTest {
private LPVSQueue webhookConfig = null;
Expand Down Expand Up @@ -213,11 +215,11 @@ public void testSaveFileWithEmptyPatchedLines() {
String directoryPath = "testDirectory";
List<String> patchedLines = new ArrayList<>();

LPVSFileUtil.saveFile(fileName, directoryPath, patchedLines);
assertFalse(LPVSFileUtil.saveFile(fileName, directoryPath, patchedLines));
Boolean result1 = Files.exists(Paths.get(directoryPath, fileName));
assert (result1.equals(false));

LPVSFileUtil.saveFile(fileName, directoryPath, null);
assertFalse(LPVSFileUtil.saveFile(fileName, directoryPath, null));
Boolean result2 = Files.exists(Paths.get(directoryPath, fileName));
assert (result2.equals(false));
}
Expand Down Expand Up @@ -279,4 +281,55 @@ private void deleteDirectory(File directory) {
}
directory.delete();
}

@Test
void testConstructorThrowsException_N() {
try {
Constructor<LPVSFileUtil> constructor = LPVSFileUtil.class.getDeclaredConstructor();
constructor.setAccessible(true);
constructor.newInstance();
fail("Expected UnsupportedOperationException to be thrown");
} catch (InvocationTargetException e) {
assertInstanceOf(
UnsupportedOperationException.class,
e.getCause(),
"UnsupportedOperationException expected");
} catch (Exception e) {
fail("Unexpected exception type thrown: " + e.getCause());
}
}

@Test
public void saveFileToDiskTest() throws IOException {
sourceDir = Files.createTempDirectory("source").toFile();
String content = "Hello, World!";
String fileName = "file.txt";
LPVSFileUtil.saveFileToDisk(sourceDir.getAbsolutePath(), fileName, content);
assertTrue(new File(sourceDir.getAbsolutePath() + File.separator + fileName).exists());
deleteDirectory(sourceDir);
}

@Test
public void saveFileToDiskTest_N() throws IOException {
sourceDir = Files.createTempDirectory("source").toFile();
String content = "Hello, World!";
String fileName =
"zxcvbnmasdfghjklqwertyuiopoiuytrewqasdfghjklmnbvcxzaqwsxcderfvbgtyhnmjuikzxcvbnmasdfsdsdsdhjhjghjklqwertyuiopoiuytrewqasdfghjklmnbvcxzaqwsxcderfvbgtyhnmjuikzxcvbnmasdfghjklqwertyuiopoiuytrewqasdfghjklmnbvcxzaqwsxcderfvbgtyhnmjuikzxcvbnmasdfghjklqwertyuiopoiuytrewqasdfg/file.txt";
assertThrows(
IOException.class,
() -> LPVSFileUtil.saveFileToDisk(sourceDir.getAbsolutePath(), fileName, content));
deleteDirectory(sourceDir);
}

@Test
public void saveFileTest_N() throws IOException {
sourceDir = Files.createTempDirectory("source").toFile();
String content = "+Hello, World!";
String fileName =
"zxcvbnmasdfghjklqwertyuiopoiuytrewqasdfghjklmnbvcxzaqwsxcderfvbgtyhnmjuikzxcvbnmasdfsdsdsdhjhjghjklqwertyuiopoiuytrewqasdfghjklmnbvcxzaqwsxcderfvbgtyhnmjuikzxcvbnmasdfghjklqwertyuiopoiuytrewqasdfghjklmnbvcxzaqwsxcderfvbgtyhnmjuikzxcvbnmasdfghjklqwertyuiopoiuytrewqasdfg/file.txt";
assertFalse(
LPVSFileUtil.saveFile(
fileName, sourceDir.getAbsolutePath(), Collections.singletonList(content)));
deleteDirectory(sourceDir);
}
}
20 changes: 20 additions & 0 deletions src/test/java/com/lpvs/util/LPVSPayloadUtilTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
import org.springframework.http.HttpHeaders;

import java.io.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.net.URISyntaxException;
import java.nio.file.Files;
import java.nio.file.Path;
Expand Down Expand Up @@ -436,4 +438,22 @@ public void testConvertInputStreamToString_ThrowsException_N() {
() -> LPVSPayloadUtil.convertInputStreamToString(inputStream));
}
}

@Test
void testConstructorThrowsException_N() {
try {
Constructor<LPVSPayloadUtil> constructor =
LPVSPayloadUtil.class.getDeclaredConstructor();
constructor.setAccessible(true);
constructor.newInstance();
fail("Expected UnsupportedOperationException to be thrown");
} catch (InvocationTargetException e) {
assertInstanceOf(
UnsupportedOperationException.class,
e.getCause(),
"UnsupportedOperationException expected");
} catch (Exception e) {
fail("Unexpected exception type thrown: " + e.getCause());
}
}
}

0 comments on commit 68e0ef8

Please sign in to comment.