diff --git a/src/main/java/org/polystat/Program.java b/src/main/java/org/polystat/Program.java index a181e209..8045d69f 100644 --- a/src/main/java/org/polystat/Program.java +++ b/src/main/java/org/polystat/Program.java @@ -26,7 +26,6 @@ import com.jcabi.xml.XML; import com.jcabi.xml.XMLDocument; -import java.nio.file.Files; import java.nio.file.Path; import java.util.List; import org.cactoos.Func; @@ -74,10 +73,14 @@ public XML apply(final String locator) throws Exception { final String[] parts = locator.split("\\."); final String name = parts[1]; final Path xml = this.temp.resolve(String.format("%s.xml", name)); - if (!Files.exists(xml)) { + final Path src = this.sources.resolve(String.format("%s.eo", name)); + if ( + !xml.toFile().exists() + || xml.toFile().lastModified() < src.toFile().lastModified() + ) { new Syntax( name, - new InputOf(this.sources.resolve(String.format("%s.eo", name))), + new InputOf(src), new OutputTo(xml) ).parse(); new Xsline( diff --git a/src/test/java/org/polystat/ProgramTest.java b/src/test/java/org/polystat/ProgramTest.java index eef23669..72dcbd05 100644 --- a/src/test/java/org/polystat/ProgramTest.java +++ b/src/test/java/org/polystat/ProgramTest.java @@ -24,13 +24,15 @@ package org.polystat; import com.jcabi.xml.XML; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; import java.nio.file.Path; +import org.cactoos.Text; import org.cactoos.io.ResourceOf; +import org.cactoos.io.TeeInput; +import org.cactoos.scalar.LengthOf; import org.cactoos.text.TextOf; import org.hamcrest.MatcherAssert; import org.hamcrest.Matchers; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; @@ -42,14 +44,44 @@ final class ProgramTest { @Test - void interpretOneEolangProgram(@TempDir final Path sources, - @TempDir final Path temp) throws Exception { - Files.write( - sources.resolve("foo.eo"), - new TextOf( - new ResourceOf("org/polystat/tests/div-by-zero.eo") - ).asString().getBytes(StandardCharsets.UTF_8) + void interpretOneEolangProgram( + @TempDir final Path sources, + @TempDir final Path temp + ) throws Exception { + this.writeSourceFile(sources); + this.assertOutput(sources, temp); + } + + @Test + void recompilesIfExpired( + @TempDir final Path sources, + @TempDir final Path temp + ) throws Exception { + this.writeSourceFile(sources); + final Path xml = temp.resolve("foo.xml"); + this.writeFile(new TextOf("INVALID"), xml); + Assertions.assertTrue( + xml.toFile().setLastModified(0L) ); + this.assertOutput(sources, temp); + } + + /** + * Write to file. + * @param data Data. + * @param file File. + */ + private void writeFile(final Text data, final Path file) { + new LengthOf(new TeeInput(data, file)).longValue(); + } + + /** + * Run program & check output. + * @param sources Source dir. + * @param temp Temp dir. + * @throws Exception If program fails. + */ + private void assertOutput(final Path sources, final Path temp) throws Exception { final Program program = new Program(sources, temp); final XML foo = program.apply("\\Phi.foo"); MatcherAssert.assertThat( @@ -58,4 +90,16 @@ void interpretOneEolangProgram(@TempDir final Path sources, ); } + /** + * Write source code. + * @param dir Output dir. + */ + private void writeSourceFile(final Path dir) { + this.writeFile( + new TextOf( + new ResourceOf("org/polystat/tests/div-by-zero.eo") + ), + dir.resolve("foo.eo") + ); + } }