Skip to content

Commit

Permalink
Support complex queries
Browse files Browse the repository at this point in the history
  • Loading branch information
lukfor committed Dec 27, 2024
1 parent f631613 commit 848cb69
Show file tree
Hide file tree
Showing 3 changed files with 156 additions and 19 deletions.
13 changes: 12 additions & 1 deletion src/main/java/com/askimed/nf/test/commands/RunTestsCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,11 @@ public class RunTestsCommand extends AbstractCommand {
"--tag" }, split = ",", description = "Execute only tests with this tag", required = false, showDefaultValue = Visibility.ALWAYS)
private List<String> tags = new Vector<String>();

@Option(names = {
"--query" }, description = "Execute only tests that match this expression", required = false)
private String query = null;


private static Logger log = LoggerFactory.getLogger(RunTestsCommand.class);

@Override
Expand Down Expand Up @@ -254,7 +259,13 @@ public Integer execute() throws Exception {
environment.setPluginManager(manager);

TestSuiteResolver testSuiteResolver = new TestSuiteResolver(environment);
List<ITestSuite> testSuits = testSuiteResolver.parse(scripts, new TagQuery(tags));

TagQuery tagQuery = new TagQuery(tags);
if (query != null) {
tagQuery = new TagQueryExpression(query);
}

List<ITestSuite> testSuits = testSuiteResolver.parse(scripts, tagQuery);

testSuits.sort(TestSuiteSorter.getDefault());
if (shard != null && !testSuits.isEmpty()) {
Expand Down
75 changes: 75 additions & 0 deletions src/main/java/com/askimed/nf/test/core/TagQueryExpression.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package com.askimed.nf.test.core;

import groovy.util.Eval;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class TagQueryExpression extends TagQuery {

private String query;

public TagQueryExpression(String query) {
this.query = query;
}

public boolean matches(ITaggable taggable) {
if (query == null || query.trim().isEmpty()) {
return true;
}

Map<String, Object> bindingContext = createBindingContext(taggable);

try {
return (Boolean) Eval.me("tags", bindingContext.get("tags"), query);
} catch (Exception e) {
throw new IllegalArgumentException("Invalid query: " + query, e);
}
}

private Map<String, Object> createBindingContext(ITaggable taggable) {
Map<String, Boolean> tagMap = new HashMap<>();
Map<String, Object> context = new HashMap<>();

// Add tags from the current taggable
taggable.getTags().forEach(tag -> {
tagMap.put(tag.toLowerCase(), true);
});
tagMap.put(taggable.getName(), true);

// Add parent tags recursively
ITaggable parent = taggable.getParent();
while (parent != null) {
parent.getTags().forEach(tag -> {
tagMap.put(tag.toLowerCase(), true);
});
tagMap.put(parent.getName(), true);
parent = parent.getParent();
}

context.put("tags", new DefaultTagMap(tagMap)); // Map for key-based access
context.put("query", query); // The actual query as a string

return context;
}

@Override
public String toString() {
return query;
}


// Custom map to handle missing keys
private static class DefaultTagMap extends HashMap<String, Boolean> {
public DefaultTagMap(Map<String, Boolean> map) {
super(map);
}

@Override
public Boolean get(Object key) {
return super.getOrDefault(key, false);
}
}
}
87 changes: 69 additions & 18 deletions src/test/java/com/askimed/nf/test/core/TestSuiteResolverTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,13 @@ public void executeTestSuiteByName() throws Throwable {
Assertions.assertTrue(tests.contains("test 1"));
Assertions.assertTrue(tests.contains("test 2"));
}
{
TagQuery query = new TagQueryExpression("tags['suite 1']");
List<String> tests = collectTests(query);
Assertions.assertEquals(2, tests.size());
Assertions.assertTrue(tests.contains("test 1"));
Assertions.assertTrue(tests.contains("test 2"));
}
}

@Test
Expand All @@ -95,36 +102,80 @@ public void executeTestsByTag() throws Throwable {
Assertions.assertEquals(1, tests.size());
Assertions.assertTrue(tests.contains("test 1"));
}
{
TagQuery query = new TagQueryExpression("tags['tag2']");
List<String> tests = collectTests(query);
Assertions.assertEquals(1, tests.size());
Assertions.assertTrue(tests.contains("test 1"));
}
}

@Test
public void executeTestsByTagAcrossSuites() throws Throwable {

TagQuery query = new TagQuery("tag5");
List<String> tests = collectTests(query);
Assertions.assertEquals(2, tests.size());
Assertions.assertTrue(tests.contains("test 2"));
Assertions.assertTrue(tests.contains("test 3"));
{
TagQuery query = new TagQuery("tag5");
List<String> tests = collectTests(query);
Assertions.assertEquals(2, tests.size());
Assertions.assertTrue(tests.contains("test 2"));
Assertions.assertTrue(tests.contains("test 3"));
}
{
TagQuery query = new TagQueryExpression("tags['tag5']");
List<String> tests = collectTests(query);
Assertions.assertEquals(2, tests.size());
Assertions.assertTrue(tests.contains("test 2"));
Assertions.assertTrue(tests.contains("test 3"));
}
{
TagQuery query = new TagQuery("!tag5");
List<String> tests = collectTests(query);
Assertions.assertEquals(1, tests.size());
Assertions.assertTrue(!tests.contains("test 2"));
Assertions.assertTrue(!tests.contains("test 3"));
}
{
TagQuery query = new TagQueryExpression("!tags['tag5']");
List<String> tests = collectTests(query);
Assertions.assertEquals(1, tests.size());
Assertions.assertTrue(!tests.contains("test 2"));
Assertions.assertTrue(!tests.contains("test 3"));
}
}

@Test
public void executeTestsBySuiteTag() throws Throwable {

TagQuery query = new TagQuery("tag1");
List<String> tests = collectTests(query);
Assertions.assertEquals(2, tests.size());
Assertions.assertTrue(tests.contains("test 1"));
Assertions.assertTrue(tests.contains("test 2"));
{
TagQuery query = new TagQuery("tag1");
List<String> tests = collectTests(query);
Assertions.assertEquals(2, tests.size());
Assertions.assertTrue(tests.contains("test 1"));
Assertions.assertTrue(tests.contains("test 2"));
}
{
TagQuery query = new TagQueryExpression("tags['tag1']");
List<String> tests = collectTests(query);
Assertions.assertEquals(2, tests.size());
Assertions.assertTrue(tests.contains("test 1"));
Assertions.assertTrue(tests.contains("test 2"));
}
}

@Test
public void executeTestsByMultipleTags() throws Throwable {

TagQuery query = new TagQuery("tag3", "tag4");
List<String> tests = collectTests(query);
Assertions.assertEquals(2, tests.size());
Assertions.assertTrue(tests.contains("test 1"));
Assertions.assertTrue(tests.contains("test 2"));
{
TagQuery query = new TagQuery("tag3", "tag4");
List<String> tests = collectTests(query);
Assertions.assertEquals(2, tests.size());
Assertions.assertTrue(tests.contains("test 1"));
Assertions.assertTrue(tests.contains("test 2"));
}
{
TagQueryExpression query = new TagQueryExpression("tags['tag3'] || tags['tag4']");
List<String> tests = collectTests(query);
Assertions.assertEquals(2, tests.size());
Assertions.assertTrue(tests.contains("test 1"));
Assertions.assertTrue(tests.contains("test 2"));
}
}

protected List<String> collectTests(TagQuery query) throws Throwable {
Expand Down

0 comments on commit 848cb69

Please sign in to comment.