Skip to content

Commit 9a600ee

Browse files
committed
feat(state): ability to load state from any test file
Closes: #69
1 parent 43ab144 commit 9a600ee

File tree

9 files changed

+103
-60
lines changed

9 files changed

+103
-60
lines changed

src/main/java/ru/ewc/checklogic/LogicChecker.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import ru.ewc.checklogic.server.CommandPage;
3131
import ru.ewc.checklogic.server.ContextPage;
3232
import ru.ewc.checklogic.server.Endpoints;
33+
import ru.ewc.checklogic.server.ResourceTemplateRender;
3334
import ru.ewc.checklogic.server.StatePage;
3435
import ru.ewc.checklogic.server.config.ConfigPage;
3536

@@ -55,11 +56,12 @@ public static void main(final String[] args) {
5556
final ServerInstance context = factory.initialState();
5657
final FullSystem minum = FullSystem.initialize();
5758
final WebFramework web = minum.getWebFramework();
59+
final ResourceTemplateRender render = new ResourceTemplateRender();
5860
registerEndpoints(web, new ConfigPage(factory.configuration()));
5961
registerEndpoints(web, new CommandPage(context));
6062
registerEndpoints(web, new ContextPage(context, factory.configuration()));
61-
registerEndpoints(web, new AllEndpoints(context, factory.configuration()));
62-
registerEndpoints(web, new StatePage(context));
63+
registerEndpoints(web, new AllEndpoints(context, factory.configuration(), render));
64+
registerEndpoints(web, new StatePage(context, factory.configuration(), render));
6365
minum.block();
6466
}
6567

src/main/java/ru/ewc/checklogic/ServerInstance.java

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,10 @@
2525
package ru.ewc.checklogic;
2626

2727
import java.net.URI;
28-
import java.nio.file.Paths;
2928
import java.util.List;
3029
import java.util.Map;
3130
import lombok.Getter;
31+
import ru.ewc.checklogic.testing.CheckSuite;
3232
import ru.ewc.decisions.api.ComputationContext;
3333
import ru.ewc.decisions.api.DecisionTables;
3434
import ru.ewc.decisions.api.DecitaException;
@@ -151,22 +151,17 @@ public void initialize() {
151151
this.context = new ComputationContext(this.state, this.getAllTables());
152152
}
153153

154-
public boolean hasTestsFolder() {
155-
return Paths.get(this.root, "tests").toFile().exists();
156-
}
157-
158-
public void createTestFolder() {
159-
Paths.get(this.root, "tests").toFile().mkdirs();
160-
this.context = new ComputationContext(this.state, this.getAllTables());
161-
}
162-
163154
public boolean isNotSpecified(final String arg) {
164155
final String[] args = arg.split("::");
165156
final boolean function = this.server.functionsLocatorName().equals(args[0]);
166157
final boolean request = this.server.requestLocatorName().equals(args[0]);
167158
return function && !this.states.functionSpecified(args[1]) || request;
168159
}
169160

161+
public void createState(final String include, final CheckSuite suite) {
162+
suite.findAndPerform(include, this.context);
163+
}
164+
170165
private DecisionTables getAllTables() {
171166
return DecisionTables.using(new CombinedCsvFileReader(this.tables, ".csv", ";"));
172167
}

src/main/java/ru/ewc/checklogic/server/AllEndpoints.java

Lines changed: 7 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -46,38 +46,20 @@ public final class AllEndpoints implements Endpoints {
4646
*/
4747
private final WebPages pages;
4848

49-
public AllEndpoints(final ServerInstance context, final ServerConfiguration config) {
49+
public AllEndpoints(
50+
final ServerInstance context,
51+
final ServerConfiguration config,
52+
final ResourceTemplateRender render
53+
) {
5054
this.context = context;
51-
this.pages = new WebPages(new ResourceTemplateRender(), context.getRoot(), config);
55+
this.pages = new WebPages(render, context.getRoot(), config);
5256
}
5357

5458
@Override
5559
public void register(final WebFramework web) {
5660
web.registerPartialPath(GET, "static", AllEndpoints::staticResource);
5761
web.registerPath(GET, "", this::httpGetRouter);
5862
web.registerPath(GET, "test", this::httpGetRouter);
59-
web.registerPath(GET, "state", this::httpGetRouter);
60-
web.registerPath(POST, "state", this::httpPostRouter);
61-
web.registerPath(POST, "test", this::httpPostRouter);
62-
}
63-
64-
private Response httpPostRouter(final Request request) {
65-
final Response result;
66-
final String address = request.requestLine().getPathDetails().getIsolatedPath();
67-
if (this.context.isEmpty()) {
68-
if ("state".equals(address)) {
69-
this.context.initialize();
70-
result = Response.htmlOk("OK", Map.of("HX-Redirect", "/"));
71-
} else {
72-
result = this.pages.uninitializedPage();
73-
}
74-
} else if (!this.context.hasTestsFolder() && "test".equals(address)) {
75-
this.context.createTestFolder();
76-
result = Response.htmlOk("OK", Map.of("HX-Redirect", "/test"));
77-
} else {
78-
result = new Response(NOT_FOUND, "", PLAIN_TEXT);
79-
}
80-
return result;
8163
}
8264

8365
private Response httpGetRouter(final Request request) {
@@ -96,13 +78,7 @@ private Response getAddressFor(final Request request) {
9678
if (address.isEmpty()) {
9779
result = this.renderHtmlFor("templates/index.html");
9880
} else if ("test".equals(address)) {
99-
if (this.context.hasTestsFolder()) {
100-
result = this.pages.testPage();
101-
} else {
102-
result = this.renderHtmlFor("templates/noTestsFolder.html");
103-
}
104-
} else if ("state".equals(address)) {
105-
result = this.pages.statePage(this.context);
81+
result = this.pages.testPage();
10682
} else {
10783
result = new Response(NOT_FOUND, "", PLAIN_TEXT);
10884
}

src/main/java/ru/ewc/checklogic/server/StatePage.java

Lines changed: 66 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,14 @@
2727
import com.renomad.minum.web.RequestLine;
2828
import com.renomad.minum.web.Response;
2929
import com.renomad.minum.web.WebFramework;
30+
import java.net.URI;
31+
import java.nio.file.Path;
3032
import java.util.Map;
33+
import java.util.stream.Collectors;
34+
import ru.ewc.checklogic.ServerConfiguration;
3135
import ru.ewc.checklogic.ServerInstance;
36+
import ru.ewc.checklogic.testing.CheckSuite;
37+
import ru.ewc.decisions.input.CombinedCsvFileReader;
3238

3339
/**
3440
* I am a class providing access to the state page.
@@ -41,18 +47,76 @@ public final class StatePage implements Endpoints {
4147
*/
4248
private final ServerInstance context;
4349

44-
public StatePage(final ServerInstance context) {
50+
/**
51+
* The server configuration.
52+
*/
53+
private final ServerConfiguration config;
54+
55+
/**
56+
* The template renderer, creating pages to be served.
57+
*/
58+
private final ResourceTemplateRender processors;
59+
60+
public StatePage(
61+
final ServerInstance context,
62+
final ServerConfiguration config,
63+
final ResourceTemplateRender processors
64+
) {
4565
this.context = context;
66+
this.config = config;
67+
this.processors = processors;
4668
}
4769

4870
@Override
4971
public void register(final WebFramework web) {
50-
web.registerPath(RequestLine.Method.DELETE, "state", this::resetState);
72+
web.registerPath(GET, "state", this::statePage);
73+
web.registerPath(POST, "state", this::createState);
74+
web.registerPath(DELETE, "state", this::resetState);
75+
}
76+
77+
private Response statePage(final Request request) {
78+
assert request.requestLine().getMethod().equals(RequestLine.Method.GET);
79+
final StoredState stored = new StoredState(this.context.storedState());
80+
return Response.htmlOk(
81+
this.processors.renderInLayout(
82+
"templates/state.html",
83+
Map.of(
84+
"state", stored.asHtmlList(),
85+
"includes", this.listOfIncludes()
86+
)
87+
)
88+
);
89+
}
90+
91+
private Response createState(final Request request) {
92+
assert request.requestLine().getMethod().equals(RequestLine.Method.POST);
93+
final String include = request.body().asString("include");
94+
this.context.createState(include, this.testSuite());
95+
return Response.htmlOk("OK", Map.of("HX-Redirect", "/state"));
5196
}
5297

5398
private Response resetState(final Request request) {
5499
assert request.requestLine().getMethod().equals(RequestLine.Method.DELETE);
55100
this.context.initialize();
56101
return Response.htmlOk("OK", Map.of("HX-Redirect", "/state"));
57102
}
103+
104+
private CheckSuite testSuite() {
105+
return CheckSuite.using(
106+
new CombinedCsvFileReader(this.testsFolder(), ".csv", ";"),
107+
this.context.getRoot(),
108+
this.config.requestLocatorName()
109+
);
110+
}
111+
112+
private URI testsFolder() {
113+
return Path.of(this.context.getRoot(), "tests").toUri();
114+
}
115+
116+
private String listOfIncludes() {
117+
return this.testSuite().checkNames().stream()
118+
.sorted()
119+
.map(name -> "<option value=\"%s\">%s</option>".formatted(name, name))
120+
.collect(Collectors.joining());
121+
}
58122
}

src/main/java/ru/ewc/checklogic/server/WebPages.java

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030
import java.util.Map;
3131
import java.util.stream.Collectors;
3232
import ru.ewc.checklogic.ServerConfiguration;
33-
import ru.ewc.checklogic.ServerInstance;
3433
import ru.ewc.checklogic.testing.CheckSuite;
3534
import ru.ewc.checklogic.testing.TestResult;
3635
import ru.ewc.decisions.input.CombinedCsvFileReader;
@@ -108,16 +107,6 @@ public Response testPage() {
108107
);
109108
}
110109

111-
public Response statePage(final ServerInstance context) {
112-
final StoredState stored = new StoredState(context.storedState());
113-
return Response.htmlOk(
114-
this.renderInLayout(
115-
"templates/state.html",
116-
Map.of("state", stored.asHtmlList())
117-
)
118-
);
119-
}
120-
121110
public String renderInLayout(final String template, final Map<String, String> values) {
122111
return this.processors.renderInLayout(template, values);
123112
}

src/main/java/ru/ewc/checklogic/testing/CheckFile.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,8 @@ public List<TestResult> performChecks(final String root, final CheckSuite files)
7676
.toList();
7777
}
7878

79-
public void performInSameContext(final ComputationContext ctx) {
79+
public void performInSameContext(final ComputationContext ctx, final CheckSuite files) {
80+
this.suite = files;
8081
this.getTestResult(this.tests.getFirst(), ctx);
8182
}
8283

src/main/java/ru/ewc/checklogic/testing/CheckSuite.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,10 @@ public List<TestResult> perform() {
7575
public void findAndPerform(final String file, final ComputationContext ctx) {
7676
this.tests.stream().filter(test -> file.equals(test.getFile()))
7777
.findFirst()
78-
.ifPresent(test -> test.performInSameContext(ctx));
78+
.ifPresent(test -> test.performInSameContext(ctx, this));
79+
}
80+
81+
public List<String> checkNames() {
82+
return this.tests.stream().map(CheckFile::getFile).toList();
7983
}
8084
}

src/main/resources/templates/state.html

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,21 @@
2525
<div class="col">
2626
<h1>State entities</h1>
2727
<div class="row">
28-
<div class="col col-4">
28+
<div class="col col-2">
2929
<button class="btn btn-primary" hx-delete="/state" hx-trigger="click">Reset</button>
3030
</div>
31+
<div class="col col-10">
32+
<form class="mb-3" hx-post="/state">
33+
<div class="input-group">
34+
<select class="form-select" id="include" name="include"
35+
placeholder="Select a state to include"
36+
aria-label="Example select with button addon">
37+
{{ includes }}
38+
</select>
39+
<button class="btn btn-primary" type="submit">Create state</button>
40+
</div>
41+
</form>
42+
</div>
3143
</div>
3244
<div class="row">
3345
{{ state }}

src/main/resources/templates/uninitialized.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,4 @@
2222
~ SOFTWARE.
2323
-->
2424
<h1>Server is not initialized</h1>
25-
<button class="btn btn-primary" hx-trigger="click" hx-post="/state" hx-swap="delete">Create barebones context</button>
25+
<p>You'll need to create the basic folder structure for the business logic source files.</p>

0 commit comments

Comments
 (0)