From 3d2061125d23dc85745a0c49d8f7fe33ea3a3011 Mon Sep 17 00:00:00 2001 From: Jonathan Shook Date: Mon, 27 Jun 2022 23:38:03 -0500 Subject: [PATCH] improve and fix spectest to document formats --- .../{types => api}/STAssemblyValidator.java | 2 +- .../{types => api}/STBuilderFacets.java | 20 ++++-- .../spectest/{types => api}/STNodeLoader.java | 2 +- .../spectest/{types => api}/STPathLoader.java | 4 +- .../{types => api}/STTypedAssembly.java | 2 +- .../nb/spectest/core/STBuilder.java | 16 +++-- .../nosqlbench/nb/spectest/core/STDebug.java | 26 ++++++++ .../nb/spectest/core/STNameAndCodeTuple.java | 19 ++---- .../nosqlbench/nb/spectest/core/STNode.java | 18 +++-- .../nb/spectest/core/STNodeAssembly.java | 4 +- .../nosqlbench/nb/spectest/core/SpecTest.java | 17 +++-- .../nb/spectest/loaders/STDefaultLoader.java | 64 ++++++------------ .../spectest/loaders/STDefaultNodeLoader.java | 53 +++++++++++++-- .../STNameCodeTuple.java | 2 +- .../STNamedCodeTuples.java | 4 +- .../STNamedNodes.java | 2 +- .../STNodeReference.java | 2 +- .../nb/spectest/traversal/STAndPredicate.java | 50 ++++++++++++++ .../nb/spectest/traversal/STArgumentRef.java | 25 +++++++ .../traversal/STBreadthFirstPredicate.java | 66 +++++++++++++++++++ .../traversal/STDeepMatchAnyPredicate.java | 53 +++++++++++++++ .../traversal/STDepthFirstPredicate.java | 59 +++++++++++++++++ .../traversal/STNodeClassPredicate.java | 41 ++++++++++++ .../traversal/STNodePatternPredicate.java | 54 +++++++++++++++ .../STNodePredicate.java | 54 ++++----------- .../STNodePredicates.java | 34 ++++++---- .../traversal/STPairWisePredicate.java | 51 ++++++++++++++ .../spectest/traversal/STPredicateVerbs.java | 47 +++++++++++++ .../nb/spectest/STNodePredicateTest.java | 2 +- .../nb/spectest/STNodePredicatesTest.java | 13 ++-- 30 files changed, 643 insertions(+), 163 deletions(-) rename nb-spectest/src/main/java/io/nosqlbench/nb/spectest/{types => api}/STAssemblyValidator.java (94%) rename nb-spectest/src/main/java/io/nosqlbench/nb/spectest/{types => api}/STBuilderFacets.java (84%) rename nb-spectest/src/main/java/io/nosqlbench/nb/spectest/{types => api}/STNodeLoader.java (95%) rename nb-spectest/src/main/java/io/nosqlbench/nb/spectest/{types => api}/STPathLoader.java (90%) rename nb-spectest/src/main/java/io/nosqlbench/nb/spectest/{types => api}/STTypedAssembly.java (94%) create mode 100644 nb-spectest/src/main/java/io/nosqlbench/nb/spectest/core/STDebug.java rename nb-spectest/src/main/java/io/nosqlbench/nb/spectest/{testtypes => testmodels}/STNameCodeTuple.java (98%) rename nb-spectest/src/main/java/io/nosqlbench/nb/spectest/{testtypes => testmodels}/STNamedCodeTuples.java (96%) rename nb-spectest/src/main/java/io/nosqlbench/nb/spectest/{testtypes => testmodels}/STNamedNodes.java (93%) rename nb-spectest/src/main/java/io/nosqlbench/nb/spectest/{testtypes => testmodels}/STNodeReference.java (93%) create mode 100644 nb-spectest/src/main/java/io/nosqlbench/nb/spectest/traversal/STAndPredicate.java create mode 100644 nb-spectest/src/main/java/io/nosqlbench/nb/spectest/traversal/STArgumentRef.java create mode 100644 nb-spectest/src/main/java/io/nosqlbench/nb/spectest/traversal/STBreadthFirstPredicate.java create mode 100644 nb-spectest/src/main/java/io/nosqlbench/nb/spectest/traversal/STDeepMatchAnyPredicate.java create mode 100644 nb-spectest/src/main/java/io/nosqlbench/nb/spectest/traversal/STDepthFirstPredicate.java create mode 100644 nb-spectest/src/main/java/io/nosqlbench/nb/spectest/traversal/STNodeClassPredicate.java create mode 100644 nb-spectest/src/main/java/io/nosqlbench/nb/spectest/traversal/STNodePatternPredicate.java rename nb-spectest/src/main/java/io/nosqlbench/nb/spectest/{loaders => traversal}/STNodePredicate.java (65%) rename nb-spectest/src/main/java/io/nosqlbench/nb/spectest/{loaders => traversal}/STNodePredicates.java (78%) create mode 100644 nb-spectest/src/main/java/io/nosqlbench/nb/spectest/traversal/STPairWisePredicate.java create mode 100644 nb-spectest/src/main/java/io/nosqlbench/nb/spectest/traversal/STPredicateVerbs.java diff --git a/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/types/STAssemblyValidator.java b/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/api/STAssemblyValidator.java similarity index 94% rename from nb-spectest/src/main/java/io/nosqlbench/nb/spectest/types/STAssemblyValidator.java rename to nb-spectest/src/main/java/io/nosqlbench/nb/spectest/api/STAssemblyValidator.java index 47aafcd9f..e31a6591d 100644 --- a/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/types/STAssemblyValidator.java +++ b/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/api/STAssemblyValidator.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.nosqlbench.nb.spectest.types; +package io.nosqlbench.nb.spectest.api; import io.nosqlbench.nb.spectest.core.STNodeAssembly; diff --git a/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/types/STBuilderFacets.java b/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/api/STBuilderFacets.java similarity index 84% rename from nb-spectest/src/main/java/io/nosqlbench/nb/spectest/types/STBuilderFacets.java rename to nb-spectest/src/main/java/io/nosqlbench/nb/spectest/api/STBuilderFacets.java index 9ef2c9e80..3ae9f2889 100644 --- a/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/types/STBuilderFacets.java +++ b/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/api/STBuilderFacets.java @@ -14,19 +14,19 @@ * limitations under the License. */ -package io.nosqlbench.nb.spectest.types; +package io.nosqlbench.nb.spectest.api; import com.vladsch.flexmark.util.ast.Node; import io.nosqlbench.nb.spectest.core.SpecTest; import io.nosqlbench.nb.spectest.core.STBuilder; -import io.nosqlbench.nb.spectest.loaders.STNodePredicate; -import io.nosqlbench.nb.spectest.loaders.STNodePredicates; +import io.nosqlbench.nb.spectest.traversal.STNodePredicate; +import io.nosqlbench.nb.spectest.traversal.STNodePredicates; import java.nio.file.Path; public interface STBuilderFacets { - interface All extends WantsPaths, WantsPathsOrScannersOrValidators, WantsScannersOrValidators {} + interface All extends WantsPaths, WantsPathsOrScannersOrValidators, WantsScannersOrValidators, WantsDebuggingOptions {} interface WantsPaths { /** @@ -94,7 +94,10 @@ public interface STBuilderFacets { * is resumed on the next element not included in the result.

* *

The predicates can be one of the types supported by {@link STNodePredicate} - * and {@link STNodePredicates}.

+ * and {@link STNodePredicates}. These can be wrapped in structural predicate form + * by using the helpers from {@link io.nosqlbench.nb.spectest.traversal.STPredicateVerbs}, + * particularly with an import like + *
{@code import static io.nosqlbench.nb.spectest.traversal.STPredicateVerbs.*;}

* * @param predicates The pattern to match * @return this SpecTestBuilder for builder method chaining @@ -102,10 +105,13 @@ public interface STBuilderFacets { WantsValidatorsOrDone matchNodes(Object... predicates); } - interface WantsValidatorsOrDone extends Done{ - Done validators(STAssemblyValidator... validators); + interface WantsValidatorsOrDone extends WantsDebuggingOptions { + WantsDebuggingOptions validators(STAssemblyValidator... validators); } + interface WantsDebuggingOptions extends Done { + Done debug(); + } interface Done { SpecTest build(); } diff --git a/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/types/STNodeLoader.java b/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/api/STNodeLoader.java similarity index 95% rename from nb-spectest/src/main/java/io/nosqlbench/nb/spectest/types/STNodeLoader.java rename to nb-spectest/src/main/java/io/nosqlbench/nb/spectest/api/STNodeLoader.java index 75e68efc7..2d9d1a8bf 100644 --- a/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/types/STNodeLoader.java +++ b/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/api/STNodeLoader.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.nosqlbench.nb.spectest.types; +package io.nosqlbench.nb.spectest.api; import com.vladsch.flexmark.util.ast.Node; import io.nosqlbench.nb.spectest.core.STNodeAssembly; diff --git a/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/types/STPathLoader.java b/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/api/STPathLoader.java similarity index 90% rename from nb-spectest/src/main/java/io/nosqlbench/nb/spectest/types/STPathLoader.java rename to nb-spectest/src/main/java/io/nosqlbench/nb/spectest/api/STPathLoader.java index b991fe437..97f43e357 100644 --- a/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/types/STPathLoader.java +++ b/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/api/STPathLoader.java @@ -14,10 +14,10 @@ * limitations under the License. */ -package io.nosqlbench.nb.spectest.types; +package io.nosqlbench.nb.spectest.api; import io.nosqlbench.nb.spectest.core.STNodeAssembly; -import io.nosqlbench.nb.spectest.loaders.STNodePredicates; +import io.nosqlbench.nb.spectest.traversal.STNodePredicates; import java.nio.file.Path; import java.util.List; diff --git a/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/types/STTypedAssembly.java b/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/api/STTypedAssembly.java similarity index 94% rename from nb-spectest/src/main/java/io/nosqlbench/nb/spectest/types/STTypedAssembly.java rename to nb-spectest/src/main/java/io/nosqlbench/nb/spectest/api/STTypedAssembly.java index 204e3164c..e95dadd43 100644 --- a/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/types/STTypedAssembly.java +++ b/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/api/STTypedAssembly.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.nosqlbench.nb.spectest.types; +package io.nosqlbench.nb.spectest.api; import io.nosqlbench.nb.spectest.core.STNodeAssembly; diff --git a/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/core/STBuilder.java b/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/core/STBuilder.java index 834a06f03..db07466e3 100644 --- a/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/core/STBuilder.java +++ b/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/core/STBuilder.java @@ -17,10 +17,10 @@ package io.nosqlbench.nb.spectest.core; import io.nosqlbench.nb.spectest.loaders.STDefaultLoader; -import io.nosqlbench.nb.spectest.loaders.STNodePredicate; -import io.nosqlbench.nb.spectest.types.STAssemblyValidator; -import io.nosqlbench.nb.spectest.types.STBuilderFacets; -import io.nosqlbench.nb.spectest.types.STPathLoader; +import io.nosqlbench.nb.spectest.traversal.STNodePredicate; +import io.nosqlbench.nb.spectest.api.STAssemblyValidator; +import io.nosqlbench.nb.spectest.api.STBuilderFacets; +import io.nosqlbench.nb.spectest.api.STPathLoader; import java.nio.file.Path; import java.util.ArrayList; @@ -32,6 +32,7 @@ public abstract class STBuilder implements STBuilderFacets.All { protected List paths = new ArrayList<>(); protected List scanners = new ArrayList<>(); protected List validators = new ArrayList<>(); + protected boolean debug; @Override public STBuilderFacets.WantsPathsOrScannersOrValidators paths(Path... paths) { @@ -56,9 +57,14 @@ public abstract class STBuilder implements STBuilderFacets.All { } @Override - public STBuilderFacets.Done validators(STAssemblyValidator... validators) { + public STBuilderFacets.WantsDebuggingOptions validators(STAssemblyValidator... validators) { this.validators.addAll(Arrays.asList(validators)); return this; } + @Override + public STBuilderFacets.Done debug() { + this.debug=true; + return this; + } } diff --git a/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/core/STDebug.java b/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/core/STDebug.java new file mode 100644 index 000000000..f004ea530 --- /dev/null +++ b/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/core/STDebug.java @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2022 nosqlbench + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.nosqlbench.nb.spectest.core; + +public interface STDebug { + void applyDebugging(boolean enabled); + static void applyDebugging(boolean enabled, Object maybeDebuggable) { + if (maybeDebuggable instanceof STDebug d) { + d.applyDebugging(enabled); + } + } +} diff --git a/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/core/STNameAndCodeTuple.java b/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/core/STNameAndCodeTuple.java index a382ac07b..99fd25c32 100644 --- a/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/core/STNameAndCodeTuple.java +++ b/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/core/STNameAndCodeTuple.java @@ -16,29 +16,24 @@ package io.nosqlbench.nb.spectest.core; -import io.nosqlbench.nb.spectest.testtypes.STNodeReference; +import io.nosqlbench.nb.spectest.testmodels.STNodeReference; import java.nio.file.Path; -public class STNameAndCodeTuple implements STNodeReference { - - private final STNode nameNode; - private final STNode dataNode; - public STNameAndCodeTuple(STNode nameNode, STNode dataNode) { - this.nameNode = nameNode; - this.dataNode = dataNode; - } +public record STNameAndCodeTuple( + STNode nameNode, + STNode dataNode +) implements STNodeReference { public String getDesc() { return nameNode.getDesc(); } - public String getName() { - return nameNode.text.toString(); + return nameNode.getText(); } public String getData() { - return dataNode.text.toString(); + return dataNode.getText(); } @Override diff --git a/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/core/STNode.java b/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/core/STNode.java index ff800bb98..c1baf974a 100644 --- a/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/core/STNode.java +++ b/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/core/STNode.java @@ -35,13 +35,17 @@ public final class STNode { private final Path path; private final int line; private final Node refnode; - public CharSequence info; - public CharSequence text; + private final CharSequence text; public STNode(Supplier desc, Node dataNode, Path path) { this.description = desc.get().toString(); - this.text = dataNode.getFirstChild().getChars(); - this.line = dataNode.getFirstChild().getLineNumber(); + if (dataNode.getFirstChild()!=null) { + this.text = dataNode.getFirstChild().getChars(); + this.line = dataNode.getFirstChild().getLineNumber(); + } else { + this.text = ""; + this.line = dataNode.getLineNumber(); + } this.path = path; this.refnode = dataNode; } @@ -96,7 +100,6 @@ public final class STNode { if (!Objects.equals(description, that.description)) return false; if (!Objects.equals(path, that.path)) return false; if (!Objects.equals(refnode, that.refnode)) return false; - if (!Objects.equals(info, that.info)) return false; return Objects.equals(text, that.text); } @@ -106,8 +109,11 @@ public final class STNode { result = 31 * result + (path != null ? path.hashCode() : 0); result = 31 * result + line; result = 31 * result + (refnode != null ? refnode.hashCode() : 0); - result = 31 * result + (info != null ? info.hashCode() : 0); result = 31 * result + (text != null ? text.hashCode() : 0); return result; } + + public String getText() { + return text.toString(); + } } diff --git a/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/core/STNodeAssembly.java b/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/core/STNodeAssembly.java index 61a9785b8..e0a3fe1de 100644 --- a/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/core/STNodeAssembly.java +++ b/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/core/STNodeAssembly.java @@ -17,7 +17,7 @@ package io.nosqlbench.nb.spectest.core; import com.vladsch.flexmark.util.ast.Node; -import io.nosqlbench.nb.spectest.testtypes.STNamedCodeTuples; +import io.nosqlbench.nb.spectest.testmodels.STNamedCodeTuples; import java.nio.file.Path; import java.security.InvalidParameterException; @@ -75,7 +75,7 @@ public class STNodeAssembly extends ArrayList { public String getAsText(int index) { assertRange(index); - return get(index).text.toString(); + return get(index).getText(); } public Path getPath() { diff --git a/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/core/SpecTest.java b/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/core/SpecTest.java index 5302c91cb..6d5bb76c3 100644 --- a/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/core/SpecTest.java +++ b/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/core/SpecTest.java @@ -19,9 +19,9 @@ package io.nosqlbench.nb.spectest.core; import com.vladsch.flexmark.ext.yaml.front.matter.YamlFrontMatterExtension; import com.vladsch.flexmark.parser.Parser; import io.nosqlbench.nb.spectest.loaders.STFileScanner; -import io.nosqlbench.nb.spectest.types.STAssemblyValidator; -import io.nosqlbench.nb.spectest.types.STBuilderFacets; -import io.nosqlbench.nb.spectest.types.STPathLoader; +import io.nosqlbench.nb.spectest.api.STAssemblyValidator; +import io.nosqlbench.nb.spectest.api.STBuilderFacets; +import io.nosqlbench.nb.spectest.api.STPathLoader; import java.nio.file.Path; import java.util.LinkedHashSet; @@ -73,11 +73,17 @@ public class SpecTest implements Runnable { private final List paths; private final List pathLoaders; private final List validators; + private final boolean debug; - private SpecTest(List paths, List pathLoaders, List validators) { + private SpecTest(List paths, List pathLoaders, List validators, boolean debug) { this.paths = paths; this.pathLoaders = pathLoaders; this.validators = validators; + this.debug = debug; + if (debug) { + pathLoaders.forEach(p -> STDebug.applyDebugging(debug,p)); + validators.forEach(p -> STDebug.applyDebugging(debug,p)); + } } @Override @@ -99,7 +105,6 @@ public class SpecTest implements Runnable { testables.add(assembly); } } - } } @@ -117,7 +122,7 @@ public class SpecTest implements Runnable { private static class Builder extends STBuilder { @Override public SpecTest build() { - return new SpecTest(paths,scanners,validators); + return new SpecTest(paths,scanners,validators,debug); } } } diff --git a/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/loaders/STDefaultLoader.java b/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/loaders/STDefaultLoader.java index 7b38f37b2..b9fd446b3 100644 --- a/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/loaders/STDefaultLoader.java +++ b/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/loaders/STDefaultLoader.java @@ -18,64 +18,34 @@ package io.nosqlbench.nb.spectest.loaders; import com.vladsch.flexmark.ext.yaml.front.matter.YamlFrontMatterExtension; import com.vladsch.flexmark.parser.Parser; +import io.nosqlbench.nb.spectest.api.STNodeLoader; +import io.nosqlbench.nb.spectest.api.STPathLoader; +import io.nosqlbench.nb.spectest.core.STDebug; import io.nosqlbench.nb.spectest.core.STNodeAssembly; -import io.nosqlbench.nb.spectest.types.STAssemblyValidator; -import io.nosqlbench.nb.spectest.types.STNodeLoader; -import io.nosqlbench.nb.spectest.types.STPathLoader; +import io.nosqlbench.nb.spectest.traversal.STNodePredicates; import java.nio.file.Path; import java.security.InvalidParameterException; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; -/** - *

This scanner looks for testable specifications which are matched as a sequence of - * 3 2-tuples, described in {@link YamlSpecValidator}. The required markdown structure for - * this looks like: - *

{@code
- * ## call form with defaults
- *
- * *yaml:*
- * ```yaml
- * name: TEMPLATE(myname,thedefault)
- * ```
- *
- * *json:*
- * ```json5
- * {
- *     "name": "thedefault"
- * }
- * ```
- *
- * *ops:*
- * ```json5
- * []
- * ```
- * }
- *

- * - *

Specifically, the emphasis and colon paragraph blocks indicate the naming of the elements, and the - * fenced code sections represent the content. The name elements are not matched for the name specifically, - * although the {@link STAssemblyValidator} which consumes these {@link STNodeAssembly}s will interpret them - * as described above. - *

- * - */ -public class STDefaultLoader implements STPathLoader { +public class STDefaultLoader implements STPathLoader, STDebug { private final STNodePredicates predicates; private static final Parser parser = Parser.builder().extensions(List.of(YamlFrontMatterExtension.create())).build(); + private boolean debug; public STDefaultLoader(Object... predicates) { if (predicates.length==0) { throw new InvalidParameterException("An empty spec scanner is invalid."); } - if ((predicates.length % 2) != 0) { - throw new InvalidParameterException("You can only provide predicates in sequences of 2-tuples, where" + - "each even index is a naming element and each odd index is the associated test content. " + - "But " + predicates.length + " were provided: " + Arrays.toString(predicates)); - } + + // No longer valid? + // if ((predicates.length % 2) != 0) { + // throw new InvalidParameterException("You can only provide predicates in sequences of 2-tuples, where" + + // "each even index is a naming element and each odd index is the associated test content. " + + // "But " + predicates.length + " were provided: " + Arrays.toString(predicates)); + // } this.predicates = new STNodePredicates(predicates); } @@ -84,13 +54,19 @@ public class STDefaultLoader implements STPathLoader { List assemblies = new ArrayList<>(); List matchingPaths = STFileScanner.findMatching(specPath); STNodeLoader nodeLoader = new STDefaultNodeLoader(predicates); + STDebug.applyDebugging(debug,nodeLoader); for (Path matchingPath : matchingPaths) { List found = nodeLoader.apply(matchingPath, null); assemblies.addAll(found); } - return assemblies; } + + @Override + public void applyDebugging(boolean enabled) { + this.debug =enabled; + STDebug.applyDebugging(enabled,predicates); + } } diff --git a/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/loaders/STDefaultNodeLoader.java b/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/loaders/STDefaultNodeLoader.java index 40db6d743..e04139fb0 100644 --- a/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/loaders/STDefaultNodeLoader.java +++ b/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/loaders/STDefaultNodeLoader.java @@ -20,9 +20,11 @@ import com.vladsch.flexmark.ext.yaml.front.matter.YamlFrontMatterExtension; import com.vladsch.flexmark.parser.Parser; import com.vladsch.flexmark.util.ast.Document; import com.vladsch.flexmark.util.ast.Node; +import io.nosqlbench.nb.spectest.api.STNodeLoader; +import io.nosqlbench.nb.spectest.core.STDebug; import io.nosqlbench.nb.spectest.core.STNode; import io.nosqlbench.nb.spectest.core.STNodeAssembly; -import io.nosqlbench.nb.spectest.types.STNodeLoader; +import io.nosqlbench.nb.spectest.traversal.STNodePredicates; import java.io.IOException; import java.nio.file.Files; @@ -32,10 +34,11 @@ import java.util.ArrayList; import java.util.List; import java.util.Optional; -public class STDefaultNodeLoader implements STNodeLoader { +public class STDefaultNodeLoader implements STNodeLoader, STDebug { private final STNodePredicates predicates; private final Parser parser = Parser.builder().extensions(List.of(YamlFrontMatterExtension.create())).build(); + private boolean debug; public STDefaultNodeLoader(Object... predicates) { @@ -55,8 +58,8 @@ public class STDefaultNodeLoader implements STNodeLoader { public List apply(Path path, Node node) { List assemblies = new ArrayList<>(); - if (node==null) { - if (path==null) { + if (node == null) { + if (path == null) { throw new InvalidParameterException("You must provide at least a path."); } try { @@ -67,7 +70,7 @@ public class STDefaultNodeLoader implements STNodeLoader { } } if (node instanceof Document d) { - node=d.getFirstChild(); + node = d.getFirstChild(); } STHeadingScanner headings = new STHeadingScanner(" > "); @@ -79,11 +82,25 @@ public class STDefaultNodeLoader implements STNodeLoader { if (optionalStanza.isPresent()) { List found = optionalStanza.get(); - List stnodes = found.stream().map(n -> new STNode(headings, n, path)).toList(); - STNodeAssembly testassy = new STNodeAssembly(stnodes.toArray(new STNode[0])); + + List stnodes = found.stream() + .map( + n -> new STNode(headings, n, path) + ) + .toList(); + + STNodeAssembly testassy = new STNodeAssembly( + stnodes.toArray( + new STNode[0] + ) + ); + node = found.get(found.size() - 1); headings.index(); assemblies.add(testassy); + if (debug) { + summarize(testassy); + } } if (node != null) { node = node.getNext(); @@ -92,4 +109,26 @@ public class STDefaultNodeLoader implements STNodeLoader { return assemblies; } + + private void summarize(STNodeAssembly testassy) { + for (STNode stNode : testassy) { + String nodeClass = stNode.getRefNode().getClass().getSimpleName(); + String text = stNode.getRefNode().getChars().toString(); + + String[] lines = text.split("\n"); + String header =lines[0].substring(0,Math.min(lines[0].length(),39)); + if (lines[0].length()>39) { + header=header+"..."; + } + if (!header.endsWith("\n")) { + header = header+"\n"; + } + System.out.format("%-20s|%-40s|(%-3d lines)\n",nodeClass,header.replaceAll("\n","\\n"),lines.length); + } + } + + @Override + public void applyDebugging(boolean enabled) { + this.debug = enabled; + } } diff --git a/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/testtypes/STNameCodeTuple.java b/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/testmodels/STNameCodeTuple.java similarity index 98% rename from nb-spectest/src/main/java/io/nosqlbench/nb/spectest/testtypes/STNameCodeTuple.java rename to nb-spectest/src/main/java/io/nosqlbench/nb/spectest/testmodels/STNameCodeTuple.java index 02da0e668..d45511b7e 100644 --- a/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/testtypes/STNameCodeTuple.java +++ b/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/testmodels/STNameCodeTuple.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.nosqlbench.nb.spectest.testtypes; +package io.nosqlbench.nb.spectest.testmodels; import com.vladsch.flexmark.util.ast.Node; diff --git a/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/testtypes/STNamedCodeTuples.java b/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/testmodels/STNamedCodeTuples.java similarity index 96% rename from nb-spectest/src/main/java/io/nosqlbench/nb/spectest/testtypes/STNamedCodeTuples.java rename to nb-spectest/src/main/java/io/nosqlbench/nb/spectest/testmodels/STNamedCodeTuples.java index ae058f218..1c5fea8eb 100644 --- a/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/testtypes/STNamedCodeTuples.java +++ b/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/testmodels/STNamedCodeTuples.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.nosqlbench.nb.spectest.testtypes; +package io.nosqlbench.nb.spectest.testmodels; import io.nosqlbench.nb.spectest.core.STNameAndCodeTuple; import io.nosqlbench.nb.spectest.core.STNode; @@ -67,7 +67,7 @@ public class STNamedCodeTuples { public String getTypeSignature() { StringBuilder sb = new StringBuilder(); for (STNameAndCodeTuple tuple : tuples) { - sb.append(tuple.getDesc()).append("->"); + sb.append(tuple.getName()).append("->"); } sb.setLength(sb.length()-"->".length()); return sb.toString().replaceAll("[^-a-zA-Z0-9<> _]", ""); diff --git a/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/testtypes/STNamedNodes.java b/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/testmodels/STNamedNodes.java similarity index 93% rename from nb-spectest/src/main/java/io/nosqlbench/nb/spectest/testtypes/STNamedNodes.java rename to nb-spectest/src/main/java/io/nosqlbench/nb/spectest/testmodels/STNamedNodes.java index 986050488..427cdd735 100644 --- a/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/testtypes/STNamedNodes.java +++ b/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/testmodels/STNamedNodes.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.nosqlbench.nb.spectest.testtypes; +package io.nosqlbench.nb.spectest.testmodels; public class STNamedNodes { diff --git a/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/testtypes/STNodeReference.java b/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/testmodels/STNodeReference.java similarity index 93% rename from nb-spectest/src/main/java/io/nosqlbench/nb/spectest/testtypes/STNodeReference.java rename to nb-spectest/src/main/java/io/nosqlbench/nb/spectest/testmodels/STNodeReference.java index ea3b16b2e..94348ffe9 100644 --- a/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/testtypes/STNodeReference.java +++ b/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/testmodels/STNodeReference.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.nosqlbench.nb.spectest.testtypes; +package io.nosqlbench.nb.spectest.testmodels; import java.nio.file.Path; diff --git a/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/traversal/STAndPredicate.java b/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/traversal/STAndPredicate.java new file mode 100644 index 000000000..b2a50e0a7 --- /dev/null +++ b/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/traversal/STAndPredicate.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2022 nosqlbench + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.nosqlbench.nb.spectest.traversal; + +import com.vladsch.flexmark.util.ast.Node; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Predicate; +import java.util.stream.Collectors; + +public class STAndPredicate implements Predicate { + private final List predicates = new ArrayList<>(); + + public STAndPredicate(Object... specs) { + for (Object predicate : specs) { + predicates.add(new STNodePredicate(predicate)); + } + } + + @Override + public boolean test(Node node) { + for (int i = 0; i < predicates.size(); i++) { + STNodePredicate predicate = predicates.get(i); + if (!predicate.test(node)) { + return false; + } + } + return true; + } + + @Override + public String toString() { + return "AND(" + predicates.stream().map(Object::toString).collect(Collectors.joining(","))+")"; + } +} diff --git a/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/traversal/STArgumentRef.java b/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/traversal/STArgumentRef.java new file mode 100644 index 000000000..061ff029a --- /dev/null +++ b/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/traversal/STArgumentRef.java @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2022 nosqlbench + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.nosqlbench.nb.spectest.traversal; + +/** + * A symblic reference to an earlier argument in the same list, to avoid duplication and expose + * uniformity in a visual way. + * @param argidx The argument index (0-based) of the previous argument to reference + */ +public record STArgumentRef(int argidx) { +} diff --git a/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/traversal/STBreadthFirstPredicate.java b/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/traversal/STBreadthFirstPredicate.java new file mode 100644 index 000000000..41d408c2d --- /dev/null +++ b/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/traversal/STBreadthFirstPredicate.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2022 nosqlbench + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.nosqlbench.nb.spectest.traversal; + +import com.vladsch.flexmark.util.ast.Node; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Predicate; +import java.util.stream.Collectors; + +/** + * Match if all the predicates match when tested pair-wise across the AST nodes, traversing + * strictly across by sibling nodes, and not following beyond the current parent. + * @return true if all siblings match + */ +public class STBreadthFirstPredicate implements Predicate { + private final List predicates = new ArrayList<>(); + + public STBreadthFirstPredicate(Object... specs) { + for (Object predicate : specs) { + predicates.add(new STNodePredicate(predicate)); + } + } + + @Override + public boolean test(Node node) { + Node focus = null; + Node parent = node.getParent(); + + for (int i = 0; i < predicates.size(); i++) { + if (focus==null) { + focus = node; + } else { + focus = focus.getNext(); + if (focus==null || parent!=focus.getParent()) { + return false; + } + } + STNodePredicate predicate = predicates.get(i); + if (!predicate.test(focus)) { + return false; + } + } + return true; + } + + @Override + public String toString() { + return "BREADTH(" + predicates.stream().map(Object::toString).collect(Collectors.joining(","))+")"; + } +} diff --git a/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/traversal/STDeepMatchAnyPredicate.java b/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/traversal/STDeepMatchAnyPredicate.java new file mode 100644 index 000000000..2f138c16b --- /dev/null +++ b/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/traversal/STDeepMatchAnyPredicate.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2022 nosqlbench + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.nosqlbench.nb.spectest.traversal; + +import com.vladsch.flexmark.util.ast.Node; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Predicate; +import java.util.stream.Collectors; + +public class STDeepMatchAnyPredicate implements Predicate { + private final List predicates = new ArrayList<>(); + + public STDeepMatchAnyPredicate(Object... specs) { + for (Object predicate : specs) { + predicates.add(new STNodePredicate(predicate)); + } + } + + @Override + public boolean test(Node node) { + for (STNodePredicate predicate: predicates) { + Node focus = node; + while (focus!=null) { + if (predicate.test(focus)) { + return true; + } + focus = focus.getFirstChild(); + } + } + return false; + } + + @Override + public String toString() { + return "DEEPANY(" + predicates.stream().map(Object::toString).collect(Collectors.joining(",")) + ")"; + } +} diff --git a/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/traversal/STDepthFirstPredicate.java b/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/traversal/STDepthFirstPredicate.java new file mode 100644 index 000000000..c4698050e --- /dev/null +++ b/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/traversal/STDepthFirstPredicate.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2022 nosqlbench + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.nosqlbench.nb.spectest.traversal; + +import com.vladsch.flexmark.util.ast.Node; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Predicate; +import java.util.stream.Collectors; + +public class STDepthFirstPredicate implements Predicate { + private final List predicates = new ArrayList<>(); + + public STDepthFirstPredicate(Object... specs) { + for (Object predicate : specs) { + predicates.add(new STNodePredicate(predicate)); + } + } + + @Override + public boolean test(Node node) { + Node focus = null; + for (int i = 0; i < predicates.size(); i++) { + if (focus == null) { + focus = node; + } else { + focus = focus.getFirstChild(); + if (focus==null) { + return false; + } + } + STNodePredicate predicate = predicates.get(i); + if (!predicate.test(focus)) { + return false; + } + } + return true; + } + + @Override + public String toString() { + return "DEPTH(" + predicates.stream().map(Object::toString).collect(Collectors.joining(",")) + ")"; + } +} diff --git a/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/traversal/STNodeClassPredicate.java b/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/traversal/STNodeClassPredicate.java new file mode 100644 index 000000000..c39336c9f --- /dev/null +++ b/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/traversal/STNodeClassPredicate.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2022 nosqlbench + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.nosqlbench.nb.spectest.traversal; + +import com.vladsch.flexmark.util.ast.Node; + +import java.util.function.Predicate; + +final class STNodeClassPredicate implements Predicate { + private final Class matchingClass; + + public STNodeClassPredicate(Class matchingClass) { + this.matchingClass = matchingClass; + } + + @Override + public boolean test(Node node) { + Class classToMatch = node.getClass(); + boolean matches = matchingClass.equals(classToMatch); + return matches; + } + + @Override + public String toString() { + return "CLASS(" + matchingClass.getSimpleName() + ")"; + } +} diff --git a/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/traversal/STNodePatternPredicate.java b/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/traversal/STNodePatternPredicate.java new file mode 100644 index 000000000..3765aa6c5 --- /dev/null +++ b/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/traversal/STNodePatternPredicate.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2022 nosqlbench + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.nosqlbench.nb.spectest.traversal; + +import com.vladsch.flexmark.util.ast.Node; +import com.vladsch.flexmark.util.sequence.BasedSequence; + +import java.util.function.Predicate; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +final class STNodePatternPredicate implements Predicate { + private final Pattern pattern; + + public STNodePatternPredicate(Pattern pattern) { + this.pattern = pattern; + } + + public STNodePatternPredicate(String pattern) { + String newPattern = (pattern.matches("^[a-zA-Z0-9]") ? ".*" : "") + pattern + (pattern.matches("[a-zA-Z0-9]$") ? ".*" : ""); + Pattern compiled = Pattern.compile(newPattern, Pattern.MULTILINE | Pattern.DOTALL); + this.pattern = compiled; + } + + @Override + public boolean test(Node node) { + if (node == null) { + return false; + } + BasedSequence chars = node.getChars(); + Matcher matcher = pattern.matcher(chars); + boolean matches = matcher.matches(); + return matches; + } + + @Override + public String toString() { + return "PATTERN(" + this.pattern.pattern() + ")"; + } +} diff --git a/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/loaders/STNodePredicate.java b/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/traversal/STNodePredicate.java similarity index 65% rename from nb-spectest/src/main/java/io/nosqlbench/nb/spectest/loaders/STNodePredicate.java rename to nb-spectest/src/main/java/io/nosqlbench/nb/spectest/traversal/STNodePredicate.java index 22b459e76..fd480f92c 100644 --- a/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/loaders/STNodePredicate.java +++ b/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/traversal/STNodePredicate.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.nosqlbench.nb.spectest.loaders; +package io.nosqlbench.nb.spectest.traversal; import com.vladsch.flexmark.ast.Paragraph; import com.vladsch.flexmark.util.ast.Node; @@ -22,7 +22,6 @@ import com.vladsch.flexmark.util.sequence.BasedSequence; import java.util.function.Predicate; import java.util.function.Supplier; -import java.util.regex.Matcher; import java.util.regex.Pattern; /** @@ -57,57 +56,21 @@ public class STNodePredicate implements Predicate, Supplier { private Predicate resolvePredicate(Object object) { if (object instanceof Predicate predicate) { - Paragraph paragraph = new Paragraph(BasedSequence.of("test paragraph")); + Paragraph paragraph = new Paragraph(BasedSequence.of("type checking")); + // assert no runtime type casting issues predicate.test(paragraph); return predicate; } else if (object instanceof Class c) { - return new ClassPredicate(c); + return new STNodeClassPredicate(c); } else if (object instanceof Pattern p) { - return new PatternPredicate(p); + return new STNodePatternPredicate(p); } else if (object instanceof CharSequence cs) { - return new PatternPredicate(cs.toString()); + return new STNodePatternPredicate(cs.toString()); } else { throw new RuntimeException("no Node predicate for type " + object.getClass().getSimpleName()); } } - private final static class ClassPredicate implements Predicate { - private final Class matchingClass; - - public ClassPredicate(Class matchingClass) { - this.matchingClass = matchingClass; - } - - @Override - public boolean test(Node node) { - Class classToMatch = node.getClass(); - boolean matches = matchingClass.equals(classToMatch); - return matches; - } - } - - private final static class PatternPredicate implements Predicate { - private final Pattern pattern; - - private PatternPredicate(Pattern pattern) { - this.pattern = pattern; - } - - private PatternPredicate(String pattern) { - String newPattern = (pattern.matches("^[a-zA-Z0-9]") ? ".*" : "") + pattern + (pattern.matches("[a-zA-Z0-9]$") ? ".*" : ""); - Pattern compiled = Pattern.compile(newPattern, Pattern.MULTILINE | Pattern.DOTALL); - this.pattern = compiled; - } - - @Override - public boolean test(Node node) { - BasedSequence chars = node.getChars(); - Matcher matcher = pattern.matcher(chars); - boolean matches = matcher.matches(); - return matches; - } - } - @Override public boolean test(Node node) { this.found = null; @@ -122,4 +85,9 @@ public class STNodePredicate implements Predicate, Supplier { public Node get() { return this.found; } + + @Override + public String toString() { + return this.predicate.toString(); + } } diff --git a/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/loaders/STNodePredicates.java b/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/traversal/STNodePredicates.java similarity index 78% rename from nb-spectest/src/main/java/io/nosqlbench/nb/spectest/loaders/STNodePredicates.java rename to nb-spectest/src/main/java/io/nosqlbench/nb/spectest/traversal/STNodePredicates.java index caf8cd7c3..a9f8b7242 100644 --- a/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/loaders/STNodePredicates.java +++ b/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/traversal/STNodePredicates.java @@ -14,9 +14,10 @@ * limitations under the License. */ -package io.nosqlbench.nb.spectest.loaders; +package io.nosqlbench.nb.spectest.traversal; import com.vladsch.flexmark.util.ast.Node; +import io.nosqlbench.nb.spectest.core.STDebug; import java.security.InvalidParameterException; import java.util.ArrayList; @@ -24,6 +25,7 @@ import java.util.List; import java.util.Optional; import java.util.function.Function; import java.util.function.Predicate; +import java.util.stream.Collectors; /** *

{@link STNodePredicates} is a convenient wrapper around {@link STNodePredicate} @@ -36,25 +38,20 @@ import java.util.function.Predicate; * a regular expression which would match "__a__" or "__b__" and then two more subsequent * matches against similar content, for a total of 3 consecutive matching nodes.

*/ -public class STNodePredicates implements Function>> { - final List> predicates; - final List found = new ArrayList<>(); - - public STNodePredicates(STNodePredicates predicates) { - this.predicates = predicates.predicates; - } +public class STNodePredicates implements Function>>, STDebug { + private final List> predicates = new ArrayList<>(); + private final List found = new ArrayList<>(); + private boolean debug; public STNodePredicates(Object... predicateSpecs) { - this.predicates = new ArrayList>(predicateSpecs.length); - for (int i = 0; i < predicateSpecs.length; i++) { if (predicateSpecs[i] instanceof STNodePredicates pspecs) { predicates.addAll(pspecs.predicates); - } else if (predicateSpecs[i] instanceof Number number) { - if (i > number.intValue()) { - predicates.add(predicates.get(number.intValue())); + } else if (predicateSpecs[i] instanceof STArgumentRef number) { + if (i > number.argidx()) { + predicates.add(predicates.get(number.argidx())); } else { - throw new InvalidParameterException("predicate reference at " + i + " references invalid position at " + number.intValue()); + throw new InvalidParameterException("predicate reference at " + i + " references invalid position at " + number.argidx()); } } else { predicates.add(new STNodePredicate(predicateSpecs[i])); @@ -88,4 +85,13 @@ public class STNodePredicates implements Function>> { return true; } + @Override + public String toString() { + return this.predicates.stream().map(Object::toString).collect(Collectors.joining(","))+")"; + } + + @Override + public void applyDebugging(boolean enabled) { + this.debug = enabled; + } } diff --git a/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/traversal/STPairWisePredicate.java b/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/traversal/STPairWisePredicate.java new file mode 100644 index 000000000..b44083d30 --- /dev/null +++ b/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/traversal/STPairWisePredicate.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2022 nosqlbench + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.nosqlbench.nb.spectest.traversal; + +import com.vladsch.flexmark.util.ast.Node; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Predicate; +import java.util.stream.Collectors; + +public class STPairWisePredicate implements Predicate> { + private final List predicates = new ArrayList<>(); + + public STPairWisePredicate(Object... specs) { + for (Object predicate : specs) { + predicates.add(new STNodePredicate(predicate)); + } + } + + + @Override + public boolean test(List nodes) { + for (int i = 0; i < predicates.size(); i++) { + if (!predicates.get(i).test(nodes.get(i))) { + return false; + } + } + return true; + } + + @Override + public String toString() { + return "PAIRWISE(" + predicates.stream().map(Object::toString).collect(Collectors.joining(","))+")"; + } + +} diff --git a/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/traversal/STPredicateVerbs.java b/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/traversal/STPredicateVerbs.java new file mode 100644 index 000000000..41f622801 --- /dev/null +++ b/nb-spectest/src/main/java/io/nosqlbench/nb/spectest/traversal/STPredicateVerbs.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2022 nosqlbench + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.nosqlbench.nb.spectest.traversal; + +public class STPredicateVerbs { + + /** + * see {@link STBreadthFirstPredicate} for details. + */ + public static STBreadthFirstPredicate breadth(Object... specs) { + return new STBreadthFirstPredicate(specs); + } + + public static STDepthFirstPredicate depth(Object... specs) { + return new STDepthFirstPredicate(specs); + } + + public static STPairWisePredicate pairwise(Object... specs) { + return new STPairWisePredicate(specs); + } + + public static STAndPredicate and(Object... specs) { + return new STAndPredicate(specs); + } + + public static STDeepMatchAnyPredicate deepany(Object... specs) { + return new STDeepMatchAnyPredicate(specs); + } + + public static STArgumentRef ref(int ref) { + return new STArgumentRef(ref); + } +} diff --git a/nb-spectest/src/test/java/io/nosqlbench/nb/spectest/STNodePredicateTest.java b/nb-spectest/src/test/java/io/nosqlbench/nb/spectest/STNodePredicateTest.java index fccf8494a..9580eb0e1 100644 --- a/nb-spectest/src/test/java/io/nosqlbench/nb/spectest/STNodePredicateTest.java +++ b/nb-spectest/src/test/java/io/nosqlbench/nb/spectest/STNodePredicateTest.java @@ -16,7 +16,7 @@ package io.nosqlbench.nb.spectest; -import io.nosqlbench.nb.spectest.loaders.STNodePredicate; +import io.nosqlbench.nb.spectest.traversal.STNodePredicate; import org.junit.jupiter.api.Test; import java.util.function.Predicate; diff --git a/nb-spectest/src/test/java/io/nosqlbench/nb/spectest/STNodePredicatesTest.java b/nb-spectest/src/test/java/io/nosqlbench/nb/spectest/STNodePredicatesTest.java index ec2de60c0..b41a484f7 100644 --- a/nb-spectest/src/test/java/io/nosqlbench/nb/spectest/STNodePredicatesTest.java +++ b/nb-spectest/src/test/java/io/nosqlbench/nb/spectest/STNodePredicatesTest.java @@ -21,22 +21,23 @@ import com.vladsch.flexmark.parser.Parser; import com.vladsch.flexmark.util.ast.Document; import io.nosqlbench.nb.spectest.core.STNodeAssembly; import io.nosqlbench.nb.spectest.loaders.STDefaultNodeLoader; -import io.nosqlbench.nb.spectest.loaders.STNodePredicates; -import io.nosqlbench.nb.spectest.types.STNodeLoader; +import io.nosqlbench.nb.spectest.traversal.STNodePredicates; +import io.nosqlbench.nb.spectest.api.STNodeLoader; import org.junit.jupiter.api.Test; import java.util.List; +import static io.nosqlbench.nb.spectest.traversal.STPredicateVerbs.ref; import static org.assertj.core.api.Assertions.assertThat; public class STNodePredicatesTest { @Test public void testBackReferences() { - STNodePredicates predicateShouldMatch1 = new STNodePredicates(".*__\\w__.*", 0, 0); - STNodePredicates predicateShouldMatch2 = new STNodePredicates("__\\w__", 0, 0); - STNodePredicates predicateShouldNotMatch3 = new STNodePredicates("^__\\w__", 0, 0); - STNodePredicates predicateShouldNotMatch4 = new STNodePredicates("^__\\w__$", 0, 0); + STNodePredicates predicateShouldMatch1 = new STNodePredicates(".*__\\w__.*", ref(0), ref(0)); + STNodePredicates predicateShouldMatch2 = new STNodePredicates("__\\w__", ref(0), ref(0)); + STNodePredicates predicateShouldNotMatch3 = new STNodePredicates("^__\\w__", ref(0), ref(0)); + STNodePredicates predicateShouldNotMatch4 = new STNodePredicates("^__\\w__$", ref(0), ref(0)); String testMarkdown = """ paragraph contents with __a__.