diff --git a/eo-maven-plugin/src/test/java/org/eolang/maven/CacheTest.java b/eo-maven-plugin/src/test/java/org/eolang/maven/CacheTest.java index 1df5dfa3a54..5991e37d308 100644 --- a/eo-maven-plugin/src/test/java/org/eolang/maven/CacheTest.java +++ b/eo-maven-plugin/src/test/java/org/eolang/maven/CacheTest.java @@ -6,8 +6,14 @@ import com.yegor256.Mktmp; import com.yegor256.MktmpResolver; +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.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.Base64; import java.util.concurrent.atomic.AtomicInteger; import org.hamcrest.MatcherAssert; import org.hamcrest.Matchers; @@ -17,10 +23,6 @@ /** * Test for {@link Cache}. * @since 0.60 - * @todo #4846:30min Add more tests for Cache class. - * Currently only two basic tests are implemented. More tests should be added to cover edge cases - * and ensure robustness of the caching mechanism. - * For example, you can add a test to verify the behavior when the source file is modified. */ @ExtendWith(MktmpResolver.class) final class CacheTest { @@ -78,4 +80,82 @@ void readsFromCacheWhenUnchanged(@Mktmp final Path temp) throws Exception { Matchers.equalTo(1) ); } + + @Test + void compilesAgainWhenChanged(@Mktmp final Path temp) throws Exception { + final var base = temp.resolve("cache-base-dir"); + Files.createDirectories(base); + final var source = temp.resolve("stdout.eo"); + Files.writeString(source, "[] > main\n (stdout \"Hello, EO!\") > @\n"); + final var target = temp.resolve("stdout.xmir"); + final var counter = new AtomicInteger(0); + final var cache = new Cache( + base, + p -> String.format("compiled %d", counter.incrementAndGet()) + ); + cache.apply(source, target, source.getFileName()); + MatcherAssert.assertThat( + "Compilation should happen once", + counter.get(), + Matchers.equalTo(1) + ); + Files.writeString(source, "[] > main\n (stdout \"Hello, EO! Modified\") > @\n"); + cache.apply(source, target, source.getFileName()); + MatcherAssert.assertThat( + "Compilation should happen again after source change", + counter.get(), + Matchers.equalTo(2) + ); + } + + @Test + void compilesIfHashExistsButCacheMissing(@Mktmp final Path temp) throws Exception { + final var base = temp.resolve("cache-root"); + Files.createDirectories(base); + final var source = temp.resolve("data.eo"); + Files.writeString(source, "[] > main\n (stdout \"Data EO\") > @\n"); + final var target = temp.resolve("data.xmir"); + final var counter = new AtomicInteger(0); + final var cache = new Cache( + base, + p -> String.format("data %d", counter.incrementAndGet()) + ); + final Path tail = source.getFileName(); + cache.apply(source, target, tail); + MatcherAssert.assertThat( + "Compilation should happen once", + counter.get(), + Matchers.equalTo(1) + ); + Files.delete(base.resolve(tail)); + cache.apply(source, target, tail); + MatcherAssert.assertThat( + "Compilation should happen again after cache deletion", + counter.get(), + Matchers.equalTo(2) + ); + } + + @Test + void writesCorrectShaHash(@Mktmp final Path temp) throws IOException, NoSuchAlgorithmException { + final var base = temp.resolve("cache"); + Files.createDirectories(base); + final var source = temp.resolve("message.txt"); + final String msg = "hello"; + final Charset encoding = StandardCharsets.UTF_8; + Files.writeString(source, msg, encoding); + final var target = temp.resolve("out.txt"); + final var tail = source.getFileName(); + final var cache = new Cache(base, p -> "compiled"); + cache.apply(source, target, tail); + MatcherAssert.assertThat( + "SHA-256 hash file has incorrect content", + Files.readString(base.resolve(String.format("%s.sha256", tail)), encoding), + Matchers.equalTo( + Base64.getEncoder().encodeToString( + MessageDigest.getInstance("SHA-256").digest(msg.getBytes(encoding)) + ) + ) + ); + } }