From 609878ca2f6b3940c293ba7575f6d717e847d94a 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: Mon, 16 Sep 2024 09:49:55 +0400 Subject: [PATCH] feat(test): ability to include tests inside tests only the first rule in the test right now, will be expanded later. Closes: #66 --- .../ru/ewc/checklogic/server/WebPages.java | 6 ++- .../ru/ewc/checklogic/testing/CheckFile.java | 54 ++++++++++++------- .../ru/ewc/checklogic/testing/CheckSuite.java | 32 ++++++++--- .../tic-tac-toe/tests/00-initialize.csv | 2 +- .../tic-tac-toe/tests/01-first-move.csv | 2 +- .../tic-tac-toe/tests/02-second-move.csv | 2 +- 6 files changed, 68 insertions(+), 30 deletions(-) diff --git a/src/main/java/ru/ewc/checklogic/server/WebPages.java b/src/main/java/ru/ewc/checklogic/server/WebPages.java index de28886..87491c9 100644 --- a/src/main/java/ru/ewc/checklogic/server/WebPages.java +++ b/src/main/java/ru/ewc/checklogic/server/WebPages.java @@ -81,10 +81,12 @@ public Response uninitializedPage() { public Response testPage() { final CheckSuite suite = CheckSuite.using( - new CombinedCsvFileReader(Path.of(this.root, "tests").toUri(), ".csv", ";") + new CombinedCsvFileReader(Path.of(this.root, "tests").toUri(), ".csv", ";"), + this.root, + this.config.requestLocatorName() ); final long start = System.currentTimeMillis(); - final List results = suite.perform(this.root, this.config.requestLocatorName()); + final List results = suite.perform(); final String rows = results.stream() .sorted(Comparator.naturalOrder()) .map(TestResult::asHtmlTableRow) diff --git a/src/main/java/ru/ewc/checklogic/testing/CheckFile.java b/src/main/java/ru/ewc/checklogic/testing/CheckFile.java index 7ef31d1..631bbb7 100644 --- a/src/main/java/ru/ewc/checklogic/testing/CheckFile.java +++ b/src/main/java/ru/ewc/checklogic/testing/CheckFile.java @@ -26,6 +26,7 @@ import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; +import lombok.Getter; import ru.ewc.checklogic.ServerContextFactory; import ru.ewc.decisions.api.ComputationContext; import ru.ewc.decisions.api.OutputTracker; @@ -41,27 +42,45 @@ * @since 0.4.1 */ public final class CheckFile { + /** + * The file containing the tests. + */ + @Getter + private final String file; + /** * The collection of single tests inside the file. */ private final List tests; - public CheckFile(final List tests) { + /** + * The name of the request locator. + */ + private final String request; + + /** + * The link to the suite that contains this file. + */ + private CheckSuite suite; + + public CheckFile(final String file, final List tests, final String request) { + this.file = file; this.tests = tests; + this.request = request; } - public List performChecks(final String root, final String locator) { + public List performChecks(final String root, final CheckSuite files) { + this.suite = files; return this.tests.stream() - .map(rule -> CheckFile.performAndLog(root, rule, locator)) + .map(rule -> this.getTestResult(rule, ServerContextFactory.create(root).context())) .toList(); } - private static TestResult performAndLog( - final String root, - final RuleFragments rule, - final String locator - ) { - final ComputationContext ctx = ServerContextFactory.create(root).context(); + public void performInSameContext(final ComputationContext ctx) { + this.getTestResult(this.tests.getFirst(), ctx); + } + + private TestResult getTestResult(final RuleFragments rule, final ComputationContext ctx) { logCheckpoint(ctx, "%s - started".formatted(rule.header())); final OutputTracker tracker = ctx.startTracking(); final List failures = new ArrayList<>(1); @@ -72,7 +91,7 @@ private static TestResult performAndLog( failures.add(new CheckFailure(check.asString(), check.result())); } } else { - CheckFile.perform(fragment, ctx, locator); + this.perform(fragment, ctx); } } logCheckpoint(ctx, "%s - %s".formatted(rule.header(), CheckFile.desc(failures))); @@ -84,17 +103,16 @@ private static TestResult performAndLog( ); } - private static void perform( - final RuleFragment fragment, - final ComputationContext ctx, - final String locator - ) { + private void perform(final RuleFragment fragment, final ComputationContext ctx) { switch (fragment.type()) { case "ASG" -> new Assignment(fragment.left(), fragment.right()).performIn(ctx); - case "OUT" -> { - if ("execute".equals(fragment.left())) { + case "EXE" -> { + if ("command".equals(fragment.left())) { ctx.perform(fragment.right()); - ctx.resetComputationState(locator); + ctx.resetComputationState(this.request); + } + if ("include".equals(fragment.left())) { + this.suite.findAndPerform(fragment.right(), ctx); } } default -> { diff --git a/src/main/java/ru/ewc/checklogic/testing/CheckSuite.java b/src/main/java/ru/ewc/checklogic/testing/CheckSuite.java index bc81056..0b97a15 100644 --- a/src/main/java/ru/ewc/checklogic/testing/CheckSuite.java +++ b/src/main/java/ru/ewc/checklogic/testing/CheckSuite.java @@ -26,6 +26,7 @@ import java.util.Collection; import java.util.List; +import ru.ewc.decisions.api.ComputationContext; import ru.ewc.decisions.input.ContentsReader; /** @@ -41,22 +42,39 @@ public final class CheckSuite { */ private final Collection tests; - private CheckSuite(final Collection tests) { + /** + * The root directory of the business logic source files. + */ + private final String root; + + private CheckSuite(final Collection tests, final String root) { this.tests = tests; + this.root = root; } - public static CheckSuite using(final ContentsReader reader) { - return new CheckSuite(reader.readAll().stream() - .map(sl -> new CheckFile(sl.specifiedRulesFragments())) - .toList() + public static CheckSuite using( + final ContentsReader reader, + final String root, + final String request + ) { + return new CheckSuite( + reader.readAll().stream() + .map(sl -> new CheckFile(sl.fileName(), sl.specifiedRulesFragments(), request)) + .toList(), + root ); } - public List perform(final String root, final String locator) { + public List perform() { return this.tests.stream() - .map(test -> test.performChecks(root, locator)) + .map(test -> test.performChecks(this.root, this)) .flatMap(List::stream) .toList(); } + public void findAndPerform(final String file, final ComputationContext ctx) { + this.tests.stream().filter(test -> file.equals(test.getFile())) + .findFirst() + .ifPresent(test -> test.performInSameContext(ctx)); + } } diff --git a/src/test/resources/tic-tac-toe/tests/00-initialize.csv b/src/test/resources/tic-tac-toe/tests/00-initialize.csv index 4ffe641..cab915d 100644 --- a/src/test/resources/tic-tac-toe/tests/00-initialize.csv +++ b/src/test/resources/tic-tac-toe/tests/00-initialize.csv @@ -1,4 +1,4 @@ -OUT;execute;initialize +EXE;command;initialize CND;table::currentPlayer;X CND;table::nextPlayer;O CND;cells::A1;empty diff --git a/src/test/resources/tic-tac-toe/tests/01-first-move.csv b/src/test/resources/tic-tac-toe/tests/01-first-move.csv index 1982775..e5cbd02 100644 --- a/src/test/resources/tic-tac-toe/tests/01-first-move.csv +++ b/src/test/resources/tic-tac-toe/tests/01-first-move.csv @@ -12,7 +12,7 @@ ASG;cells::B3;empty;empty ASG;cells::C1;empty;empty ASG;cells::C2;empty;empty ASG;cells::C3;empty;empty -OUT;execute;computed_move;computed_move +EXE;command;computed_move;computed_move CND;cells::A1;empty;X CND;computed_move::available;false;false CND;game_state::is_over;false;false diff --git a/src/test/resources/tic-tac-toe/tests/02-second-move.csv b/src/test/resources/tic-tac-toe/tests/02-second-move.csv index 6658433..4ab9aad 100644 --- a/src/test/resources/tic-tac-toe/tests/02-second-move.csv +++ b/src/test/resources/tic-tac-toe/tests/02-second-move.csv @@ -11,7 +11,7 @@ ASG;cells::B3;empty;empty ASG;cells::C1;empty;empty ASG;cells::C2;empty;empty ASG;cells::C3;empty;empty -OUT;execute;computed_move;computed_move +EXE;command;computed_move;computed_move CND;computed_move::available;false;false CND;cells::A1;X;X CND;cells::B2;O;empty \ No newline at end of file