Skip to content

Commit 47d9c80

Browse files
committed
Merge branch 'main' into the-wgpu-moment
2 parents 787ff56 + ab9a225 commit 47d9c80

5 files changed

Lines changed: 234 additions & 5 deletions

File tree

app/build.gradle.kts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ sourceSets{
4444
kotlin{
4545
srcDirs("test")
4646
}
47+
java{
48+
srcDirs("test")
49+
}
4750
}
4851
}
4952

app/src/processing/app/UpdateCheck.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -204,12 +204,15 @@ protected boolean promptToOpenContributionManager() {
204204
*/
205205

206206

207-
protected int readInt(String filename) throws IOException {
207+
protected static int readInt(String filename) throws IOException {
208208
URL url = new URL(filename);
209-
InputStream stream = url.openStream();
209+
210+
// try-with-resources auto closes things of type "Closeable" even the code throws an error
211+
try(InputStream stream = url.openStream();
210212
InputStreamReader isr = new InputStreamReader(stream);
211-
BufferedReader reader = new BufferedReader(isr);
212-
return Integer.parseInt(reader.readLine());
213+
BufferedReader reader = new BufferedReader(isr)) {
214+
return Integer.parseInt(reader.readLine().trim());
215+
}
213216
}
214217

215218

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
package processing.app;
2+
import org.junit.jupiter.api.*;
3+
import org.junit.jupiter.api.io.TempDir;
4+
import org.mockito.MockedConstruction;
5+
import org.mockito.Mockito;
6+
7+
import java.io.*;
8+
import java.net.*;
9+
import java.nio.charset.StandardCharsets;
10+
import java.nio.file.*;
11+
12+
import static org.junit.jupiter.api.Assertions.*;
13+
import static org.mockito.Mockito.*;
14+
15+
class UpdateCheckTest {
16+
17+
@TempDir
18+
Path tempDir;
19+
20+
// Helper: write content to a temp file and return its URL string
21+
private String createTempFile(String content) throws IOException {
22+
Path file = tempDir.resolve("test.txt");
23+
Files.writeString(file, content, StandardCharsets.UTF_8);
24+
return file.toUri().toString();
25+
}
26+
27+
28+
// tests to show that the method returns what it should
29+
@Test
30+
void readInt_simpleInteger_returnsCorrectValue() throws IOException {
31+
String url = createTempFile("42\n");
32+
assertEquals(42, UpdateCheck.readInt(url));
33+
}
34+
35+
@Test
36+
void readInt_negativeInteger_returnsCorrectValue() throws IOException {
37+
String url = createTempFile("-7\n");
38+
assertEquals(-7, UpdateCheck.readInt(url));
39+
}
40+
41+
@Test
42+
void readInt_integerWithLeadingAndTrailingWhitespace_returnsCorrectValue() throws IOException {
43+
String url = createTempFile(" 100 \n");
44+
assertEquals(100, UpdateCheck.readInt(url));
45+
}
46+
47+
@Test
48+
void readInt_integerWithNoNewline_returnsCorrectValue() throws IOException {
49+
String url = createTempFile("99");
50+
assertEquals(99, UpdateCheck.readInt(url));
51+
}
52+
53+
@Test
54+
void readInt_maxInt_returnsCorrectValue() throws IOException {
55+
String url = createTempFile(String.valueOf(Integer.MAX_VALUE));
56+
assertEquals(Integer.MAX_VALUE, UpdateCheck.readInt(url));
57+
}
58+
59+
@Test
60+
void readInt_minInt_returnsCorrectValue() throws IOException {
61+
String url = createTempFile(String.valueOf(Integer.MIN_VALUE));
62+
assertEquals(Integer.MIN_VALUE, UpdateCheck.readInt(url));
63+
}
64+
65+
@Test
66+
void readInt_integerWithMultipleLines_readsOnlyFirstLine() throws IOException {
67+
String url = createTempFile("5\n10\n15");
68+
assertEquals(5, UpdateCheck.readInt(url));
69+
}
70+
71+
// checks for if errors are correctly reported
72+
@Test
73+
void readInt_nonNumericContent_throwsNumberFormatException() throws IOException {
74+
String url = createTempFile("not-a-number\n");
75+
assertThrows(NumberFormatException.class, () -> UpdateCheck.readInt(url));
76+
}
77+
78+
@Test
79+
void readInt_emptyFile_throwsNullPointerException() throws IOException {
80+
String url = createTempFile("");
81+
// readLine() returns null on empty stream → trim() throws NPE
82+
assertThrows(Exception.class, () -> UpdateCheck.readInt(url));
83+
}
84+
85+
@Test
86+
void readInt_blankLine_throwsNumberFormatException() throws IOException {
87+
String url = createTempFile(" \n");
88+
assertThrows(NumberFormatException.class, () -> UpdateCheck.readInt(url));
89+
}
90+
91+
@Test
92+
void readInt_floatValue_throwsNumberFormatException() throws IOException {
93+
String url = createTempFile("3.14\n");
94+
assertThrows(NumberFormatException.class, () -> UpdateCheck.readInt(url));
95+
}
96+
97+
@Test
98+
void readInt_overflowValue_throwsNumberFormatException() throws IOException {
99+
String url = createTempFile("99999999999999\n");
100+
assertThrows(NumberFormatException.class, () -> UpdateCheck.readInt(url));
101+
}
102+
103+
@Test
104+
void readInt_invalidUrl_throwsMalformedURLException() {
105+
assertThrows(MalformedURLException.class,
106+
() -> UpdateCheck.readInt("not-a-valid-url"));
107+
}
108+
109+
@Test
110+
void readInt_nonExistentFile_throwsIOException() {
111+
String nonExistent = tempDir.resolve("ghost.txt").toUri().toString();
112+
assertThrows(IOException.class, () -> UpdateCheck.readInt(nonExistent));
113+
}
114+
115+
// checks for if streams are closed
116+
@Test
117+
void readInt_streamIsClosedAfterSuccessfulRead() throws IOException {
118+
// Spy on the InputStream to verify close() is called
119+
Path file = tempDir.resolve("close_test.txt");
120+
Files.writeString(file, "7", StandardCharsets.UTF_8);
121+
122+
URL url = file.toUri().toURL();
123+
InputStream realStream = url.openStream();
124+
InputStream spyStream = spy(realStream);
125+
126+
try (MockedConstruction<URL> mockedUrl = mockConstruction(URL.class,
127+
(mock, ctx) -> when(mock.openStream()).thenReturn(spyStream))) {
128+
129+
UpdateCheck.readInt(file.toUri().toString());
130+
}
131+
132+
verify(spyStream, atLeastOnce()).close();
133+
}
134+
135+
@Test
136+
void readInt_streamIsClosedEvenWhenParseThrows() throws IOException {
137+
Path file = tempDir.resolve("bad_close_test.txt");
138+
Files.writeString(file, "not-a-number", StandardCharsets.UTF_8);
139+
140+
URL url = file.toUri().toURL();
141+
InputStream realStream = url.openStream();
142+
InputStream spyStream = spy(realStream);
143+
144+
try (MockedConstruction<URL> mockedUrl = mockConstruction(URL.class,
145+
(mock, ctx) -> when(mock.openStream()).thenReturn(spyStream))) {
146+
147+
assertThrows(NumberFormatException.class,
148+
() -> UpdateCheck.readInt(file.toUri().toString()));
149+
}
150+
151+
verify(spyStream, atLeastOnce()).close();
152+
}
153+
}

core/src/processing/data/Table.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4824,7 +4824,7 @@ protected float getMaxFloat() {
48244824
for (int row = 0; row < getRowCount(); row++) {
48254825
for (int col = 0; col < getColumnCount(); col++) {
48264826
float value = getFloat(row, col);
4827-
if (!Float.isNaN(value)) { // TODO no, this should be comparing to the missing value
4827+
if (Float.compare(value, missingFloat) != 0) { //value now compares to missingFloat variable
48284828
if (!found) {
48294829
max = value;
48304830
found = true;

core/test/processing/data/TableTest.java

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,74 @@ public void parseInto() {
3636
Assert.assertEquals(people[0].name, "Person1");
3737
Assert.assertEquals(people[0].age, 30);
3838
}
39+
40+
@Test
41+
public void testGetMaxFloat() {
42+
Table table = new Table();
43+
table.addColumn("col1", Table.FLOAT);
44+
table.addColumn("col2", Table.FLOAT);
45+
table.addColumn("col3", Table.FLOAT);
46+
47+
//Normal case with positive values
48+
TableRow row1 = table.addRow();
49+
row1.setFloat("col1", 5.5f);
50+
row1.setFloat("col2", 10.2f);
51+
row1.setFloat("col3", 3.7f);
52+
53+
TableRow row2 = table.addRow();
54+
row2.setFloat("col1", 15.8f);
55+
row2.setFloat("col2", 2.1f);
56+
row2.setFloat("col3", 8.9f);
57+
58+
assertEquals(15.8f, table.getMaxFloat(), 0.001f);
59+
60+
//Table with negative values
61+
Table table2 = new Table();
62+
table2.addColumn("col1", Table.FLOAT);
63+
TableRow row3 = table2.addRow();
64+
row3.setFloat("col1", -5.5f);
65+
TableRow row4 = table2.addRow();
66+
row4.setFloat("col1", -2.3f);
67+
68+
assertEquals(-2.3f, table2.getMaxFloat(), 0.001f);
69+
70+
//Table with missing values (NaN)
71+
Table table3 = new Table();
72+
table3.addColumn("col1", Table.FLOAT);
73+
table3.addColumn("col2", Table.FLOAT);
74+
75+
TableRow row5 = table3.addRow();
76+
row5.setFloat("col1", Float.NaN);
77+
row5.setFloat("col2", 7.5f);
78+
79+
TableRow row6 = table3.addRow();
80+
row6.setFloat("col1", 12.3f);
81+
row6.setFloat("col2", Float.NaN);
82+
83+
assertEquals(12.3f, table3.getMaxFloat(), 0.001f);
84+
85+
//Table with all missing values
86+
Table table4 = new Table();
87+
table4.addColumn("col1", Table.FLOAT);
88+
TableRow row7 = table4.addRow();
89+
row7.setFloat("col1", Float.NaN);
90+
TableRow row8 = table4.addRow();
91+
row8.setFloat("col1", Float.NaN);
92+
93+
assertTrue(Float.isNaN(table4.getMaxFloat()));
94+
95+
//Empty table
96+
Table table5 = new Table();
97+
table5.addColumn("col1", Table.FLOAT);
98+
99+
assertTrue(Float.isNaN(table5.getMaxFloat()));
100+
101+
//Single value
102+
Table table6 = new Table();
103+
table6.addColumn("col1", Table.FLOAT);
104+
TableRow row9 = table6.addRow();
105+
row9.setFloat("col1", 42.0f);
106+
107+
assertEquals(42.0f, table6.getMaxFloat(), 0.001f);
108+
}
39109
}

0 commit comments

Comments
 (0)