Skip to content

Commit

Permalink
Fix instanceof as predicate for value expression
Browse files Browse the repository at this point in the history
Add `instanceof` among the predicate functions when parsing value
expressions.
Add test for parsing top level value expressions
  • Loading branch information
jpbempel committed Jul 12, 2024
1 parent 63f16d7 commit 580b578
Show file tree
Hide file tree
Showing 5 changed files with 175 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ public class JsonToExpressionConverter {
"startsWith",
"endsWith",
"contains",
"matches"));
"matches",
"instanceof"));

@FunctionalInterface
interface BinaryPredicateExpressionFunction<T extends Expression> {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package com.datadog.debugger.el;

import static org.junit.jupiter.api.Assertions.assertEquals;

import com.squareup.moshi.Moshi;
import datadog.trace.bootstrap.debugger.el.Values;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import okio.Okio;
import org.junit.jupiter.api.Test;

public class ValueScriptTest {

static class Obj {
String str = "hello";
int i = 10;
List<String> list = Arrays.asList("a", "b", "c");
long l = 100_000_000_000L;
float f = 2.5F;
double d = 3.14D;
char c = 'a';
}

@Test
public void predicates() {
ValueScript valueScript = loadFromResource("/test_value_expr_01.json");
valueScript.execute(RefResolverHelper.createResolver(new Obj()));
}

@Test
public void topLevelPredicates() {
List<String> lines = loadLinesFromResource("/test_one_liner_value_expr_01.txt");
for (String line : lines) {
ValueScript valueScript = load(line);
assertEquals(
Boolean.TRUE,
valueScript.execute(RefResolverHelper.createResolver(new Obj())).getValue(),
line);
}
}

@Test
public void topLevelPrimitives() {
Object[] expectedValues =
new Object[] {
"hello",
"hello",
10L,
100_000_000_000L,
2.5D,
3.14D,
"a",
"b",
5L,
3L,
"el",
Values.NULL_OBJECT,
Boolean.TRUE,
Boolean.FALSE
};
List<String> lines = loadLinesFromResource("/test_one_liner_value_expr_02.txt");
int i = 0;
for (String line : lines) {
ValueScript valueScript = load(line);
assertEquals(
expectedValues[i],
valueScript.execute(RefResolverHelper.createResolver(new Obj())).getValue(),
line);
i++;
}
}

private static List<String> loadLinesFromResource(String resourcePath) {
try (InputStream input = ProbeConditionTest.class.getResourceAsStream(resourcePath)) {
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
return reader.lines().collect(Collectors.toList());
} catch (IOException e) {
throw new RuntimeException("Failed to load resource: " + resourcePath, e);
}
}

private static ValueScript loadFromResource(String resourcePath) {
try (InputStream input = ProbeConditionTest.class.getResourceAsStream(resourcePath)) {
Moshi moshi =
new Moshi.Builder().add(ValueScript.class, new ValueScript.ValueScriptAdapter()).build();
return moshi.adapter(ValueScript.class).fromJson(Okio.buffer(Okio.source(input)));
} catch (IOException e) {
throw new RuntimeException("Failed to load resource: " + resourcePath, e);
}
}

private static ValueScript load(String json) {
try {
Moshi moshi =
new Moshi.Builder().add(ValueScript.class, new ValueScript.ValueScriptAdapter()).build();
return moshi.adapter(ValueScript.class).fromJson(json);
} catch (IOException e) {
throw new RuntimeException("Failed to load json: " + json, e);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{"dsl": "", "json": {"eq": [{"ref": "i"}, 10]}}
{"dsl": "", "json": {"==": [{"ref": "i"}, 10]}}
{"dsl": "", "json": {"lt": [{"ref": "i"}, 11]}}
{"dsl": "", "json": {"<": [{"ref": "i"}, 11]}}
{"dsl": "", "json": {"le": [{"ref": "i"}, 10]}}
{"dsl": "", "json": {"<=": [{"ref": "i"}, 10]}}
{"dsl": "", "json": {"gt": [{"ref": "i"}, 0]}}
{"dsl": "", "json": {">": [{"ref": "i"}, 0]}}
{"dsl": "", "json": {"ge": [{"ref": "i"}, 10]}}
{"dsl": "", "json": {">=": [{"ref": "i"}, 10]}}
{"dsl": "", "json": {"not": {"eq": [{"ref": "i"}, 0]}}}
{"dsl": "", "json": {"neq": [{"ref": "i"}, 0]}}
{"dsl": "", "json": {"!=": [{"ref": "i"}, 0]}}
{"dsl": "", "json": {"not": {"isEmpty": {"ref": "list"}}}}
{"dsl": "", "json": {"hasAny": [{"ref": "list"}, {"eq": [{"ref": "@it"}, "a"]}]}}
{"dsl": "", "json": {"hasAll": [{"ref": "list"}, {"neq": [{"ref": "@it"}, "d"]}]}}
{"dsl": "", "json": {"startsWith": [{"ref": "str"}, "hel"]}}
{"dsl": "", "json": {"endsWith": [{"ref": "str"}, "llo"]}}
{"dsl": "", "json": {"contains": [{"ref": "str"}, "ll"]}}
{"dsl": "", "json": {"matches": [{"ref": "str"}, "[helo]+"]}}
{"dsl": "", "json": {"instanceof": [{"ref": "str"}, "java.lang.String"]}}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{"dsl": "", "json": {"ref": "str"}}
{"dsl": "", "json": {"getmember": [{"ref": "this"}, "str"]}}
{"dsl": "", "json": {"ref": "i"}}
{"dsl": "", "json": {"ref": "l"}}
{"dsl": "", "json": {"ref": "f"}}
{"dsl": "", "json": {"ref": "d"}}
{"dsl": "", "json": {"ref": "c"}}
{"dsl": "", "json": {"index": [{"ref": "list"}, 1]}}
{"dsl": "", "json": {"len": {"ref": "str"}}}
{"dsl": "", "json": {"count": {"ref": "list"}}}
{"dsl": "", "json": {"substring": [{"ref": "str"}, 1, 3]}}
{"dsl": "", "json": null}
{"dsl": "", "json": true}
{"dsl": "", "json": false}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"dsl": "",
"json": {
"and": [
{
"or": [
{"eq": [{"ref": "i"}, 10]},
{"==": [{"ref": "i"}, 10]},
{"lt": [{"ref": "i"}, 11]},
{"<": [{"ref": "i"}, 11]},
{"le": [{"ref": "i"}, 10]},
{"<=": [{"ref": "i"}, 10]},
{"gt": [{"ref": "i"}, 0]},
{">": [{"ref": "i"}, 0]},
{"ge": [{"ref": "i"}, 10]},
{">=": [{"ref": "i"}, 10]},
{"not": {"eq": [{"ref": "i"}, 0]}},
{"neq": [{"ref": "i"}, 0]},
{"!=": [{"ref": "i"}, 0]},
{"not": {"isEmpty": {"ref": "list"}}},
{"hasAny": [{"ref": "list"}, {"eq": [{"ref": "@it"}, "a"]}]},
{"hasAll": [{"ref": "list"}, {"neq": [{"ref": "@it"}, "d"]}]},
{"startsWith": [{"ref": "str"}, "hel"]},
{"endsWith": [{"ref": "str"}, "llo"]},
{"contains": [{"ref": "str"}, "ll"]},
{"matches": [{"ref": "str"}, "[helo]+"]},
{"instanceof": [{"ref": "str"}, "java.lang.String"]}
]
}
]
}
}

0 comments on commit 580b578

Please sign in to comment.