Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion .gitattributes
Original file line number Diff line number Diff line change
@@ -1 +1,16 @@
gradlew text eol=lf
# Normalize all text files to LF in the repository (checkout follows the platform).
* text=auto

# Scripts that must keep a specific line ending regardless of platform.
gradlew text eol=lf
*.sh text eol=lf
*.bat text eol=crlf
*.cmd text eol=crlf

# Binary assets — never touch line endings.
*.rar binary
*.jar binary
*.png binary
*.jpg binary
*.gif binary
*.ico binary
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ examples/**/Z*.java
**/examples/z/**
**/examples/testapp_mc/**
**/Debug*.java
**/TestDebugger*
.claude/**
.editorconfig
env.bat
**/TestDebugger*

# Compiled source #
###################
Expand Down
40 changes: 26 additions & 14 deletions src/test/java/io/nats/client/utils/ResourceUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;

@SuppressWarnings("DataFlowIssue")
public abstract class ResourceUtils {
public static List<String> dataAsLines(String fileName) {
return resourceAsLines("data/" + fileName);
Expand All @@ -21,37 +21,49 @@ public static InputStream dataAsInputStream(String fileName) {
}

public static List<String> resourceAsLines(String fileName) {
try {
ClassLoader classLoader = ResourceUtils.class.getClassLoader();
File file = new File(classLoader.getResource(fileName).getFile());
return Files.readAllLines(file.toPath());
try (BufferedReader r = new BufferedReader(
new InputStreamReader(open(fileName), StandardCharsets.UTF_8))) {
List<String> lines = new ArrayList<>();
for (String l; (l = r.readLine()) != null; ) lines.add(l);
return lines;
}
catch (Exception e) {
catch (IOException e) {
throw new RuntimeException(e);
}

}

public static String resourceAsString(String fileName) {
try {
ClassLoader classLoader = ResourceUtils.class.getClassLoader();
File file = new File(classLoader.getResource(fileName).getFile());
return new String(Files.readAllBytes(file.toPath()), StandardCharsets.UTF_8);
try (InputStream in = open(fileName)) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] buffer = new byte[8192];
int len;
while ((len = in.read(buffer)) != -1) {
out.write(buffer, 0, len);
}
return new String(out.toByteArray(), StandardCharsets.UTF_8);
}
catch (Exception e) {
catch (IOException e) {
throw new RuntimeException(e);
}
}

public static InputStream resourceAsInputStream(String fileName) {
try {
return ResourceUtils.class.getClassLoader().getResourceAsStream(fileName);
return open(fileName);
}
catch (Exception e) {
catch (IOException e) {
throw new RuntimeException(e);
}
}

private static InputStream open(String fileName) throws FileNotFoundException {
InputStream in = ResourceUtils.class.getClassLoader().getResourceAsStream(fileName);
if (in == null) {
throw new FileNotFoundException(fileName);
}
return in;
}

public static String createTempFile(String prefix, String suffix, String[] lines) throws IOException {
File f = File.createTempFile(prefix, suffix);
BufferedWriter writer = new BufferedWriter(new FileWriter(f));
Expand Down
33 changes: 33 additions & 0 deletions src/test/java/io/nats/client/utils/ResourceUtilsTests.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package io.nats.client.utils;

import org.junit.jupiter.api.Test;

import java.io.FileNotFoundException;

import static io.nats.client.utils.ResourceUtils.*;
import static org.junit.jupiter.api.Assertions.*;

public class ResourceUtilsTests {

private static final String MISSING = "ThisResourceDoesNotExist.json";

@Test
public void testMissingResourceIdentifiesTheFile() {
assertMissing(assertThrows(RuntimeException.class, () -> dataAsString(MISSING)));
assertMissing(assertThrows(RuntimeException.class, () -> dataAsLines(MISSING)));
assertMissing(assertThrows(RuntimeException.class, () -> dataAsInputStream(MISSING)));
}

private void assertMissing(RuntimeException e) {
Throwable cause = e.getCause();
assertInstanceOf(FileNotFoundException.class, cause);
assertTrue(cause.getMessage().contains(MISSING));
}

@Test
public void testResourceStillLoads() {
assertTrue(dataAsString("StreamConfiguration.json").contains("retention"));

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The "retention" string sentinel ties this test to the internal content of StreamConfiguration.json. If the JSON is ever reorganised, this silently breaks. Asserting non-empty is sufficient to prove the load succeeded:

Suggested change
assertTrue(dataAsString("StreamConfiguration.json").contains("retention"));
assertFalse(dataAsString("StreamConfiguration.json").isEmpty());

assertFalse(dataAsLines("StreamConfiguration.json").isEmpty());
assertNotNull(dataAsInputStream("StreamConfiguration.json"));

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dataAsInputStream returns an open InputStream that is never closed here. The stream will be cleaned up by GC eventually, but in a test it's cleaner to close it explicitly:

Suggested change
assertNotNull(dataAsInputStream("StreamConfiguration.json"));
try (InputStream is = dataAsInputStream("StreamConfiguration.json")) { assertNotNull(is); }

Or simply verify the method doesn't throw, without holding onto the stream.

}
}
Loading