From fb5ea75509409ee88810792c265bbf6789f230e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=95=D0=B2=D0=B3=D0=B5=D0=BD=D0=B8=D0=B9=20=D0=A2=D0=B5?= =?UTF-8?q?=D1=80=D0=B5=D1=85=D0=BE=D0=B2?= Date: Fri, 13 Sep 2024 11:01:34 +0400 Subject: [PATCH] refactor(test): made state creation process more extensible Refs: #64 --- .../ru/ewc/checklogic/FileStateFactory.java | 83 ++++++++----------- .../ru/ewc/checklogic/MockStateFactory.java | 16 +--- .../ewc/checklogic/ServerConfiguration.java | 31 +++++-- .../ewc/checklogic/ServerContextFactory.java | 12 +-- .../ru/ewc/checklogic/ServerInstance.java | 3 +- .../java/ru/ewc/checklogic/StateFactory.java | 27 +----- .../ru/ewc/checklogic/server/WebPages.java | 6 +- .../checklogic/ServerConfigurationTest.java | 8 +- .../checklogic/server/ContextPageTest.java | 2 +- .../server/config/ConfigPageTest.java | 2 +- .../resources/tic-tac-toe/application.yaml | 1 - 11 files changed, 82 insertions(+), 109 deletions(-) diff --git a/src/main/java/ru/ewc/checklogic/FileStateFactory.java b/src/main/java/ru/ewc/checklogic/FileStateFactory.java index 6fc7f85..2b62497 100644 --- a/src/main/java/ru/ewc/checklogic/FileStateFactory.java +++ b/src/main/java/ru/ewc/checklogic/FileStateFactory.java @@ -24,16 +24,15 @@ package ru.ewc.checklogic; import java.io.File; +import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.nio.charset.StandardCharsets; import java.nio.file.Files; -import java.nio.file.NoSuchFileException; -import java.nio.file.Path; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.stream.Collectors; import lombok.SneakyThrows; import org.yaml.snakeyaml.Yaml; import ru.ewc.decisions.api.InMemoryLocator; @@ -45,70 +44,58 @@ * * @since 0.3.2 */ -public final class FileStateFactory extends StateFactory { +public final class FileStateFactory implements StateFactory { + /** + * An instance of server configuration. + */ + private final ServerConfiguration config; /** - * Optional source of locators to be added to the initial (clean) state. + * The collection of all the state and functions locators. */ - private InputStream src; + private final List locators; - public FileStateFactory(final String root) { - super(root); + public FileStateFactory(final ServerConfiguration config) { + this.config = config; + this.locators = new ArrayList<>(1); } @Override - @SneakyThrows public State initialState() { - State state; - try (InputStream file = Files.newInputStream(Path.of(this.getRoot(), "application.yaml"))) { - state = FileStateFactory.stateFromAppConfig(file); - state.locators().putAll(this.locatorsFromFile()); - } catch (final NoSuchFileException exception) { - state = State.EMPTY; - } - return state; + this.locators.clear(); + this.loadLocatorsFromApplicationConfig(); + this.loadInMemoryRequestLocator(); + return new State(this.locators); } - @Override - public StateFactory with(final InputStream file) { - this.src = file; - return this; + private void loadInMemoryRequestLocator() { + this.locators.add( + new InMemoryLocator(this.config.requestLocatorName(), new HashMap<>()) + ); } - @Override @SneakyThrows - public void initialize() { - final File config = Path.of(this.getRoot(), "application.yaml").toFile(); - if (!config.exists() && config.createNewFile()) { - try (OutputStream out = Files.newOutputStream(config.toPath())) { + private InputStream applicationConfigFile() { + final File fileconf = this.config.applicationConfig().toFile(); + if (!fileconf.exists() && fileconf.createNewFile()) { + try (OutputStream out = Files.newOutputStream(fileconf.toPath())) { out.write("locators:\n - request\n".getBytes(StandardCharsets.UTF_8)); } } + return Files.newInputStream(this.config.applicationConfig()); } @SuppressWarnings("unchecked") - private Map locatorsFromFile() { - final Map locators = new HashMap<>(); - if (this.src != null) { - final Map> raw = - (Map>) new Yaml().loadAll(this.src).iterator().next(); - if (raw == null) { - throw new IllegalStateException( - "There is no Arrange section in the test file, you should add one" - ); - } - raw.forEach((name, data) -> locators.put(name, new InMemoryLocator(name, data))); + private void loadLocatorsFromApplicationConfig() { + try (InputStream file = this.applicationConfigFile()) { + final Map yaml = new Yaml().load(file); + this.locators.addAll( + ((List) yaml.get("locators")).stream() + .map(name -> new InMemoryLocator(name, new HashMap<>())) + .toList() + ); + } catch (final IOException exception) { + this.locators.addAll(List.of()); } - return locators; - } - - @SneakyThrows - @SuppressWarnings("unchecked") - private static State stateFromAppConfig(final InputStream file) { - final Map config = new Yaml().load(file); - return new State(((List) config.get("locators")).stream() - .map(name -> new InMemoryLocator(name, new HashMap<>())) - .collect(Collectors.toList()) - ); } } diff --git a/src/main/java/ru/ewc/checklogic/MockStateFactory.java b/src/main/java/ru/ewc/checklogic/MockStateFactory.java index 6d7e4f2..deb0877 100644 --- a/src/main/java/ru/ewc/checklogic/MockStateFactory.java +++ b/src/main/java/ru/ewc/checklogic/MockStateFactory.java @@ -23,7 +23,6 @@ */ package ru.ewc.checklogic; -import java.io.InputStream; import java.util.List; import java.util.Map; import ru.ewc.decisions.api.InMemoryLocator; @@ -34,11 +33,7 @@ * * @since 0.3.2 */ -public final class MockStateFactory extends StateFactory { - public MockStateFactory(final String root) { - super(root); - } - +public final class MockStateFactory implements StateFactory { @Override public State initialState() { return new State( @@ -49,13 +44,4 @@ public State initialState() { ); } - @Override - public StateFactory with(final InputStream file) { - return this; - } - - @Override - public void initialize() { - // do nothing - } } diff --git a/src/main/java/ru/ewc/checklogic/ServerConfiguration.java b/src/main/java/ru/ewc/checklogic/ServerConfiguration.java index d81900d..e4b352f 100644 --- a/src/main/java/ru/ewc/checklogic/ServerConfiguration.java +++ b/src/main/java/ru/ewc/checklogic/ServerConfiguration.java @@ -23,6 +23,7 @@ */ package ru.ewc.checklogic; +import java.nio.file.Path; import java.util.HashMap; import java.util.Map; @@ -32,15 +33,25 @@ * @since 0.3.2 */ public final class ServerConfiguration { + /** + * The path to a root folder of the external business logic resources. + */ + private final String root; + /** * The parameters of the context. */ - private final Map parameters = new HashMap<>( - Map.of( - "request", "request", - "command", "available" - ) - ); + private final Map parameters; + + public ServerConfiguration(final String root) { + this.root = root; + this.parameters = new HashMap<>( + Map.of( + "request", "request", + "command", "available" + ) + ); + } /** * Returns the value of the specified parameter. @@ -69,4 +80,12 @@ public String commandAvailabilityField() { public String requestLocatorName() { return this.getParameterValue("request"); } + + public Path applicationConfig() { + return Path.of(this.root, "application.yaml"); + } + + public String getRoot() { + return this.root; + } } diff --git a/src/main/java/ru/ewc/checklogic/ServerContextFactory.java b/src/main/java/ru/ewc/checklogic/ServerContextFactory.java index b8a2160..b0e8438 100644 --- a/src/main/java/ru/ewc/checklogic/ServerContextFactory.java +++ b/src/main/java/ru/ewc/checklogic/ServerContextFactory.java @@ -59,18 +59,20 @@ private ServerContextFactory( } public static ServerContextFactory testable() { + final String path = "root folder"; return new ServerContextFactory( - "root folder", - new MockStateFactory("root folder"), - new ServerConfiguration() + path, + new MockStateFactory(), + new ServerConfiguration(path) ); } public static ServerContextFactory create(final String root) { + final ServerConfiguration config = new ServerConfiguration(root); return new ServerContextFactory( root, - new FileStateFactory(root), - new ServerConfiguration() + new FileStateFactory(config), + config ); } diff --git a/src/main/java/ru/ewc/checklogic/ServerInstance.java b/src/main/java/ru/ewc/checklogic/ServerInstance.java index 45c29c7..cbe2ead 100644 --- a/src/main/java/ru/ewc/checklogic/ServerInstance.java +++ b/src/main/java/ru/ewc/checklogic/ServerInstance.java @@ -78,7 +78,7 @@ public final class ServerInstance { final ServerConfiguration server) { this.states = initial; this.server = server; - this.root = this.states.getRoot(); + this.root = this.server.getRoot(); this.state = this.states.initialState(); this.tables = tables; this.context = new ComputationContext(this.state, this.getAllTables()); @@ -153,7 +153,6 @@ public String getRoot() { } public void initialize() { - this.states.initialize(); this.state = this.states.initialState(); this.context = new ComputationContext(this.state, this.getAllTables()); } diff --git a/src/main/java/ru/ewc/checklogic/StateFactory.java b/src/main/java/ru/ewc/checklogic/StateFactory.java index 00790b6..1761f12 100644 --- a/src/main/java/ru/ewc/checklogic/StateFactory.java +++ b/src/main/java/ru/ewc/checklogic/StateFactory.java @@ -23,7 +23,6 @@ */ package ru.ewc.checklogic; -import java.io.InputStream; import ru.ewc.state.State; /** @@ -33,28 +32,6 @@ * * @since 0.3.2 */ -public abstract class StateFactory { - /** - * The root path for the external business logic resources. - */ - private final String root; - - public StateFactory(final String root) { - this.root = root; - } - - /** - * Returns the path to the root folder of the external business logic resources. - * - * @return Path to the root folder as a string. - */ - public String getRoot() { - return this.root; - } - - public abstract State initialState(); - - public abstract StateFactory with(InputStream file); - - public abstract void initialize(); +interface StateFactory { + State initialState(); } diff --git a/src/main/java/ru/ewc/checklogic/server/WebPages.java b/src/main/java/ru/ewc/checklogic/server/WebPages.java index 318c693..de28886 100644 --- a/src/main/java/ru/ewc/checklogic/server/WebPages.java +++ b/src/main/java/ru/ewc/checklogic/server/WebPages.java @@ -68,7 +68,11 @@ public WebPages( } public static WebPages testable() { - return new WebPages(new MockTemplateRender(), "root folder", new ServerConfiguration()); + return new WebPages( + new MockTemplateRender(), + "root folder", + new ServerConfiguration("root folder") + ); } public Response uninitializedPage() { diff --git a/src/test/java/ru/ewc/checklogic/ServerConfigurationTest.java b/src/test/java/ru/ewc/checklogic/ServerConfigurationTest.java index 5867e0f..a150eb1 100644 --- a/src/test/java/ru/ewc/checklogic/ServerConfigurationTest.java +++ b/src/test/java/ru/ewc/checklogic/ServerConfigurationTest.java @@ -35,7 +35,7 @@ final class ServerConfigurationTest { @Test void emptyServerContextHasDefaultRequestLocatorName() { - final ServerConfiguration context = new ServerConfiguration(); + final ServerConfiguration context = new ServerConfiguration("any"); MatcherAssert.assertThat( "New server context should have 'request' as default incoming request locator's name", context.getParameterValue("request"), @@ -45,7 +45,7 @@ void emptyServerContextHasDefaultRequestLocatorName() { @Test void emptyServerContextHasDefaultCommandAvailabilityOutcome() { - final ServerConfiguration context = new ServerConfiguration(); + final ServerConfiguration context = new ServerConfiguration("any"); MatcherAssert.assertThat( "New server context should have 'available' as default command availability outcome", context.getParameterValue("command"), @@ -55,7 +55,7 @@ void emptyServerContextHasDefaultCommandAvailabilityOutcome() { @Test void shouldUpdateRequestLocatorName() { - final ServerConfiguration context = new ServerConfiguration(); + final ServerConfiguration context = new ServerConfiguration("any"); context.setParameterValue("request", "incoming"); MatcherAssert.assertThat( "Context server should update its incoming request locator's name", @@ -66,7 +66,7 @@ void shouldUpdateRequestLocatorName() { @Test void shouldUpdateCommandAvailabilityOutcome() { - final ServerConfiguration context = new ServerConfiguration(); + final ServerConfiguration context = new ServerConfiguration("any"); context.setParameterValue("command", "enabled"); MatcherAssert.assertThat( "Context server should update its command availability outcome", diff --git a/src/test/java/ru/ewc/checklogic/server/ContextPageTest.java b/src/test/java/ru/ewc/checklogic/server/ContextPageTest.java index d811147..75e62a7 100644 --- a/src/test/java/ru/ewc/checklogic/server/ContextPageTest.java +++ b/src/test/java/ru/ewc/checklogic/server/ContextPageTest.java @@ -41,7 +41,7 @@ final class ContextPageTest { void shouldCreateMockServer() { final ContextPage target = new ContextPage( ServerInstance.testable(), - new ServerConfiguration() + new ServerConfiguration("any") ); final Response response = target.contextPage(ServerTestObjects.emptyRequest()); MatcherAssert.assertThat( diff --git a/src/test/java/ru/ewc/checklogic/server/config/ConfigPageTest.java b/src/test/java/ru/ewc/checklogic/server/config/ConfigPageTest.java index d45625c..b72f784 100644 --- a/src/test/java/ru/ewc/checklogic/server/config/ConfigPageTest.java +++ b/src/test/java/ru/ewc/checklogic/server/config/ConfigPageTest.java @@ -37,7 +37,7 @@ final class ConfigPageTest { @Test void shouldNotUpdateParametersNotPresentInTheRequest() { - final ConfigPage target = new ConfigPage(new ServerConfiguration()); + final ConfigPage target = new ConfigPage(new ServerConfiguration("any")); target.updateParametersFrom(ServerTestObjects.emptyRequest()); MatcherAssert.assertThat( "Parameters should not be updated if the Request is empty", diff --git a/src/test/resources/tic-tac-toe/application.yaml b/src/test/resources/tic-tac-toe/application.yaml index 86179b4..136fc42 100644 --- a/src/test/resources/tic-tac-toe/application.yaml +++ b/src/test/resources/tic-tac-toe/application.yaml @@ -1,4 +1,3 @@ locators: - - request - table - cells \ No newline at end of file