Skip to content

Commit

Permalink
feat(test): ability to evaluate function locator fragments as groovy …
Browse files Browse the repository at this point in the history
…scripts

Closes: #64
  • Loading branch information
nergal-perm committed Sep 13, 2024
1 parent fb5ea75 commit 16422f4
Show file tree
Hide file tree
Showing 4 changed files with 115 additions and 1 deletion.
5 changes: 5 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,11 @@
<artifactId>byte-buddy</artifactId>
<version>1.14.13</version>
</dependency>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy</artifactId>
<version>3.0.17</version>
</dependency>
</dependencies>

<build>
Expand Down
12 changes: 12 additions & 0 deletions src/main/java/ru/ewc/checklogic/FileStateFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,14 @@
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import lombok.SneakyThrows;
import org.yaml.snakeyaml.Yaml;
import ru.ewc.checklogic.testing.FunctionsLocator;
import ru.ewc.decisions.api.InMemoryLocator;
import ru.ewc.decisions.api.Locator;
import ru.ewc.state.State;
Expand Down Expand Up @@ -65,9 +67,19 @@ public State initialState() {
this.locators.clear();
this.loadLocatorsFromApplicationConfig();
this.loadInMemoryRequestLocator();
this.loadFunctionsLocator();
return new State(this.locators);
}

private void loadFunctionsLocator() {
this.locators.add(
new FunctionsLocator(
this.config.functionsLocatorName(),
Paths.get(this.config.getRoot(), "functions")
)
);
}

private void loadInMemoryRequestLocator() {
this.locators.add(
new InMemoryLocator(this.config.requestLocatorName(), new HashMap<>())
Expand Down
7 changes: 6 additions & 1 deletion src/main/java/ru/ewc/checklogic/ServerConfiguration.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ public ServerConfiguration(final String root) {
this.parameters = new HashMap<>(
Map.of(
"request", "request",
"command", "available"
"command", "available",
"function", "function"
)
);
}
Expand Down Expand Up @@ -88,4 +89,8 @@ public Path applicationConfig() {
public String getRoot() {
return this.root;
}

public String functionsLocatorName() {
return this.parameters.get("function");
}
}
92 changes: 92 additions & 0 deletions src/main/java/ru/ewc/checklogic/testing/FunctionsLocator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/*
* MIT License
*
* Copyright (c) 2024 Decision-Driven Development
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package ru.ewc.checklogic.testing;

import groovy.lang.Binding;
import groovy.util.GroovyScriptEngine;
import java.net.URL;
import java.nio.file.Path;
import java.util.HashMap;
import lombok.SneakyThrows;
import ru.ewc.decisions.api.ComputationContext;
import ru.ewc.decisions.api.DecitaException;
import ru.ewc.decisions.api.InMemoryLocator;
import ru.ewc.decisions.api.Locator;

/**
* I am a special locator that can load functions from Groovy scripts. My main responsibility is to
* run the Groovy script and return the result of the script execution.
*
* @since 0.4.1
*/
public final class FunctionsLocator implements Locator {
/**
* The locator's name.
*/
private final String name;

/**
* The in-memory locator used to store overridden values.
*/
private final InMemoryLocator locator;

/**
* Groovy script engine used to run the Groovy scripts.
*/
private final GroovyScriptEngine engine;

@SneakyThrows
public FunctionsLocator(final String name, final Path path) {
this.name = name;
this.locator = new InMemoryLocator("locator", new HashMap<>());
this.engine = new GroovyScriptEngine(new URL[]{path.toUri().toURL()});
}

@SneakyThrows
@Override
public String fragmentBy(
final String fragment,
final ComputationContext context
) throws DecitaException {
final String result;
if (this.locator.state().containsKey(fragment)) {
result = this.locator.fragmentBy(fragment, context);
} else {
final Binding binding = new Binding();
binding.setVariable("context", context);
result = this.engine.run("%s.groovy".formatted(fragment), binding).toString();
}
return result;
}

@Override
public void setFragmentValue(final String fragment, final String value) {
this.locator.setFragmentValue(fragment, value);
}

@Override
public String locatorName() {
return this.name;
}
}

0 comments on commit 16422f4

Please sign in to comment.