Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
updates
  • Loading branch information
fahad19 committed Jun 27, 2026
commit 892322a98030ddd9cf133559f5089ee2da450de6
2 changes: 0 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -836,8 +836,6 @@ $ mvn exec:java -Dexec.mainClass="com.featurevisor.cli.CLI" -Dexec.args="test --

The test runner builds base datafiles and Target datafiles, then uses a Target datafile when an assertion contains `target`.

Legacy `--with-tags`, `--with-scopes`, `--schemaVersion`, and `--schema-version` flags are accepted for compatibility but ignored.

### Benchmark

Learn more about benchmarking [here](https://featurevisor.com/docs/cli/#benchmarking).
Expand Down
14 changes: 2 additions & 12 deletions src/main/java/com/featurevisor/cli/CLI.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import com.featurevisor.sdk.Featurevisor;
import com.featurevisor.sdk.Logger;
import com.featurevisor.sdk.DatafileReader;
import com.featurevisor.sdk.Conditions;
import com.featurevisor.sdk.DatafileContent;
import com.featurevisor.sdk.Segment;
import com.fasterxml.jackson.databind.ObjectMapper;
Expand Down Expand Up @@ -637,22 +637,12 @@ private TestResult testSegment(Map<String, Object> assertion, Segment segment, L
Map<String, Object> context = (Map<String, Object>) assertion.getOrDefault("context", new HashMap<>());
Object conditions = segment.getConditions();

DatafileContent datafile = new DatafileContent();
datafile.setSchemaVersion("2");
datafile.setRevision("tester");
datafile.setFeatures(new HashMap<>());
datafile.setSegments(new HashMap<>());

DatafileReader datafileReader = new DatafileReader(new DatafileReader.DatafileReaderOptions()
.datafile(datafile)
.logger(Logger.createLogger(new Logger.CreateLoggerOptions().level(level))));

boolean hasError = false;
StringBuilder errors = new StringBuilder();
long startTime = System.nanoTime();

if (assertion.containsKey("expectedToMatch")) {
boolean actual = datafileReader.allConditionsAreMatched(conditions, context);
boolean actual = Conditions.allConditionsAreMatched(conditions, context);
boolean expected = (Boolean) assertion.get("expectedToMatch");
if (actual != expected) {
hasError = true;
Expand Down
29 changes: 27 additions & 2 deletions src/main/java/com/featurevisor/sdk/Conditions.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,13 @@
* Provides condition matching functionality
*/
public class Conditions {
/**
* Functional interface for getting regex patterns.
*/
@FunctionalInterface
public interface GetRegex {
Pattern getRegex(String regexString, String regexFlags);
}

/**
* Check if a path exists in a context object
Expand Down Expand Up @@ -54,7 +61,7 @@ private static boolean pathExists(Map<String, Object> context, String path) {
public static boolean conditionIsMatched(
Condition condition,
Map<String, Object> context,
DatafileReader.GetRegex getRegex) {
GetRegex getRegex) {

if (condition == null) {
return false;
Expand Down Expand Up @@ -189,6 +196,24 @@ public static boolean conditionIsMatched(
}
}

/**
* Check if all conditions are matched given a context.
* This mirrors the JavaScript SDK's narrow root helper without exposing the
* internal datafile reader implementation.
*/
public static boolean allConditionsAreMatched(Object conditions, Map<String, Object> context) {
DatafileContent datafile = new DatafileContent();
datafile.setSchemaVersion("2");
datafile.setRevision("matcher");
datafile.setFeatures(new java.util.HashMap<>());
datafile.setSegments(new java.util.HashMap<>());

return new DatafileReader(new DatafileReader.DatafileReaderOptions()
.datafile(datafile)
.logger(Logger.createLogger(new Logger.CreateLoggerOptions())))
.allConditionsAreMatched(conditions, context);
}

private static boolean equals(Object contextValue, Object conditionValue) {
if (contextValue == null && conditionValue == null) {
return true;
Expand Down Expand Up @@ -270,7 +295,7 @@ private static boolean lessThanOrEquals(Object contextValue, Object conditionVal
return ((Number) contextValue).doubleValue() <= ((Number) conditionValue).doubleValue();
}

private static boolean matches(Object contextValue, Object conditionValue, String regexFlags, DatafileReader.GetRegex getRegex) {
private static boolean matches(Object contextValue, Object conditionValue, String regexFlags, GetRegex getRegex) {
if (!(contextValue instanceof String) || !(conditionValue instanceof String)) {
return false;
}
Expand Down
12 changes: 2 additions & 10 deletions src/main/java/com/featurevisor/sdk/DatafileReader.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,7 @@
* DatafileReader for Featurevisor SDK
* Handles reading and parsing datafile content
*/
public class DatafileReader {

/**
* Functional interface for getting regex patterns
*/
@FunctionalInterface
public interface GetRegex {
Pattern getRegex(String regexString, String regexFlags);
}
class DatafileReader {

/**
* Options for creating a DatafileReader
Expand Down Expand Up @@ -199,7 +191,7 @@ public boolean allConditionsAreMatched(Object conditions, Map<String, Object> co
return false;
}

GetRegex getRegex = (regexString, regexFlags) -> this.getRegex(regexString, regexFlags);
Conditions.GetRegex getRegex = (regexString, regexFlags) -> this.getRegex(regexString, regexFlags);

// Handle Condition object
if (conditions instanceof Condition) {
Expand Down
6 changes: 3 additions & 3 deletions src/main/java/com/featurevisor/sdk/EvaluateOptions.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public EvaluateOptions(String type, String featureKey, String variableKey) {
public Map<String, Object> getContext() { return context; }
public Logger getLogger() { return logger; }
public ModulesManager getModulesManager() { return modulesManager; }
public DatafileReader getDatafileReader() { return datafileReader; }
DatafileReader getDatafileReader() { return datafileReader; }
public Map<String, Object> getSticky() { return sticky; }
public String getDefaultVariationValue() { return defaultVariationValue; }
public Object getDefaultVariableValue() { return defaultVariableValue; }
Expand All @@ -59,7 +59,7 @@ public EvaluateOptions(String type, String featureKey, String variableKey) {
public void setContext(Map<String, Object> context) { this.context = context; }
public void setLogger(Logger logger) { this.logger = logger; }
public void setModulesManager(ModulesManager modulesManager) { this.modulesManager = modulesManager; }
public void setDatafileReader(DatafileReader datafileReader) { this.datafileReader = datafileReader; }
void setDatafileReader(DatafileReader datafileReader) { this.datafileReader = datafileReader; }
public void setSticky(Map<String, Object> sticky) { this.sticky = sticky; }
public void setDefaultVariationValue(String defaultVariationValue) { this.defaultVariationValue = defaultVariationValue; }
public void setDefaultVariableValue(Object defaultVariableValue) { this.defaultVariableValue = defaultVariableValue; }
Expand Down Expand Up @@ -96,7 +96,7 @@ public EvaluateOptions modulesManager(ModulesManager modulesManager) {
return this;
}

public EvaluateOptions datafileReader(DatafileReader datafileReader) {
EvaluateOptions datafileReader(DatafileReader datafileReader) {
this.datafileReader = datafileReader;
return this;
}
Expand Down