From 35d68d884ed72b6ee67dfab9bd2cbc6d931bf09f Mon Sep 17 00:00:00 2001 From: ulic-youthlic Date: Sun, 1 Jun 2025 02:22:14 +0800 Subject: [PATCH] Add white box test for randomWalk. --- app/build.gradle.kts | 2 + app/src/main/java/fun/youthlic/GraphCLI.java | 2 +- .../java/fun/youthlic/GraphCLIHelperTest.java | 50 ++++- gradlew.bat | 188 +++++++++--------- 4 files changed, 145 insertions(+), 97 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index bec3688..9351f90 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -36,6 +36,8 @@ dependencies { implementation("org.jline:jline:3.29.0") compileOnly("com.github.spotbugs:spotbugs-annotations:3.1.3") + + testImplementation("org.mockito:mockito-core:5.+") } // Apply a specific Java toolchain to ease working on different environments. diff --git a/app/src/main/java/fun/youthlic/GraphCLI.java b/app/src/main/java/fun/youthlic/GraphCLI.java index 73a16c5..bc681b4 100644 --- a/app/src/main/java/fun/youthlic/GraphCLI.java +++ b/app/src/main/java/fun/youthlic/GraphCLI.java @@ -331,7 +331,7 @@ class GraphCLIHelper { String randomWalk() { final var text = String.join(" ", graph.randomWalk()); - final Path path = Paths.get("output.txt"); + final Path path = Paths.get(System.getProperty("user.dir"), "output.txt"); try { Files.write(path, text.getBytes()); } catch (final IOException e) { diff --git a/app/src/test/java/fun/youthlic/GraphCLIHelperTest.java b/app/src/test/java/fun/youthlic/GraphCLIHelperTest.java index 7b46438..1fce845 100644 --- a/app/src/test/java/fun/youthlic/GraphCLIHelperTest.java +++ b/app/src/test/java/fun/youthlic/GraphCLIHelperTest.java @@ -1,8 +1,19 @@ package fun.youthlic; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; +import org.mockito.MockedStatic; -import static org.junit.jupiter.api.Assertions.assertEquals; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.PrintStream; +import java.nio.file.AccessDeniedException; +import java.nio.file.Files; +import java.nio.file.Path; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mockStatic; public class GraphCLIHelperTest { private final GraphCLIHelper graph = new GraphCLIHelper("B D E H A C D H A F D H A B G H A C G H A D G H"); @@ -12,6 +23,7 @@ public class GraphCLIHelperTest { var result = graph.queryBridgeWords("x", "a"); assertEquals("No x or a in the graph!", result); } + @Test void testWord2NotInGraph() { String result = graph.queryBridgeWords("a", "x"); @@ -45,7 +57,7 @@ public class GraphCLIHelperTest { @Test void testThreeBridgeWords() { String result = graph.queryBridgeWords("a", "g"); - assertEquals("The bridge words from a to g are: c, b, and d.", result); + assertEquals("The bridge words from a to g are: d, c, and b.", result); } @Test @@ -77,4 +89,38 @@ public class GraphCLIHelperTest { String result = graph.queryBridgeWords("B", "E"); assertEquals("The bridge words from B to E are: d.", result); } + + @Test + void testNormalExecution(@TempDir Path tempDir) throws IOException { + System.setProperty("user.dir", tempDir.toString()); + + String result = graph.randomWalk(); + + assertNotNull(result); + assertFalse(result.isEmpty()); + Path outputPath = tempDir.resolve("output.txt"); + System.out.println(outputPath); + assertTrue(Files.exists(outputPath)); + + String fileContent = Files.readString(outputPath); + assertEquals(fileContent, result); + } + + @Test + void testWritePermissionDenied() { + try (MockedStatic mockedFiles = mockStatic(Files.class)) { + mockedFiles.when(() -> Files.write(any(Path.class), any(byte[].class))) + .thenThrow(new AccessDeniedException("Permission denied")); + ByteArrayOutputStream errContent = new ByteArrayOutputStream(); + System.setErr(new PrintStream(errContent)); + + String result = graph.randomWalk(); + + assertNotNull(result); + + String errorOutput = errContent.toString(); + assertTrue(errorOutput.contains("Failed to write to file")); + assertTrue(errorOutput.contains("AccessDeniedException")); + } + } } diff --git a/gradlew.bat b/gradlew.bat index 9b42019..9d21a21 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -1,94 +1,94 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem -@rem SPDX-License-Identifier: Apache-2.0 -@rem - -@if "%DEBUG%"=="" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%"=="" set DIRNAME=. -@rem This is normally unused -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if %ERRORLEVEL% equ 0 goto execute - -echo. 1>&2 -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 -echo. 1>&2 -echo Please set the JAVA_HOME variable in your environment to match the 1>&2 -echo location of your Java installation. 1>&2 - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. 1>&2 -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 -echo. 1>&2 -echo Please set the JAVA_HOME variable in your environment to match the 1>&2 -echo location of your Java installation. 1>&2 - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if %ERRORLEVEL% equ 0 goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -set EXIT_CODE=%ERRORLEVEL% -if %EXIT_CODE% equ 0 set EXIT_CODE=1 -if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% -exit /b %EXIT_CODE% - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega