-
Notifications
You must be signed in to change notification settings - Fork 26
Add Jmespath expression function #1790
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: support-objects-in-expressions
Are you sure you want to change the base?
Changes from 3 commits
1ed1350
d0f37d5
373f3e9
25469e6
b3af6b4
e05eec5
9e4315a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| using System.Text.Json; | ||
| using DevLab.JmesPath; | ||
|
|
||
| namespace Altinn.App.Core.Internal.Expressions; | ||
|
|
||
| internal sealed class JmespathFunctionEvaluator | ||
| { | ||
| private readonly ExpressionValue[] _args; | ||
|
|
||
| public JmespathFunctionEvaluator(ExpressionValue[] args) => _args = args; | ||
|
|
||
| public ExpressionValue Evaluate() | ||
| { | ||
| if (_args.Length != 2) | ||
| { | ||
| throw new ExpressionEvaluatorTypeErrorException($"Expected 2 argument(s), got {_args.Length}"); | ||
| } | ||
| if (_args[1].ValueKind != JsonValueKind.String) | ||
| { | ||
| throw new ExpressionEvaluatorTypeErrorException($"Expected argument to be string, got {_args[1]}"); | ||
| } | ||
| return Implementation(_args[0], _args[1].String); | ||
| } | ||
|
|
||
| private static ExpressionValue Implementation(ExpressionValue data, string query) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Implementation funker, men du kunne vell også brukt overloading her og kalt den det samme som metoden som kaller den, Evaluate. Syns kanskje det blir hakket bedre, men er jo litt smak og behag dette med navngivning, du får vurdere det selv.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Her valgte jeg samme format som i
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fikset. Valgte å kalle den |
||
| { | ||
| string resultAsString = VerifyAndRunQuery(data, query); | ||
| JsonElement result = JsonSerializer.Deserialize<JsonElement>(resultAsString); | ||
| return ExpressionValue.FromJsonElement(result); | ||
| } | ||
|
|
||
| private static string VerifyAndRunQuery(ExpressionValue data, string query) | ||
| { | ||
| JmesPath jmesPath = new(); | ||
| try | ||
| { | ||
| return jmesPath.Transform(data.ToString(), query); | ||
|
olavsorl marked this conversation as resolved.
Outdated
|
||
| } | ||
| catch (Exception exception) | ||
| { | ||
| throw new ExpressionEvaluatorTypeErrorException($"Jmespath error: \"{exception.Message}\""); | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,150 @@ | ||
| { | ||
| "name": "jmespath", | ||
| "testCases": [ | ||
| { | ||
| "name": "Works with a simple property query that returns a string", | ||
| "expression": ["jmespath", ["object", "name", "Kari"], "name"], | ||
| "expects": "Kari" | ||
| }, | ||
| { | ||
| "name": "Works with a simple property query that returns a number", | ||
| "expression": ["jmespath", ["object", "ageInYears", 18], "ageInYears"], | ||
| "expects": 18 | ||
| }, | ||
| { | ||
| "name": "Works with a simple property query that returns a boolean", | ||
| "expression": ["jmespath", ["object", "likesIceCream", true], "likesIceCream"], | ||
| "expects": true | ||
| }, | ||
| { | ||
| "name": "Works with a simple property query that returns null", | ||
| "expression": ["jmespath", ["object", "favouriteColour", null], "favouriteColour"], | ||
| "expects": null | ||
| }, | ||
| { | ||
| "name": "Works with a simple property query that returns an object", | ||
| "expression": [ | ||
| "jmespath", | ||
| [ | ||
| "object", | ||
| "person", | ||
| [ | ||
| "object", | ||
| "name", "Kari", | ||
| "ageInYears", 18, | ||
| "likesIceCream", true, | ||
| "favouriteColour", null | ||
| ] | ||
| ], | ||
| "person" | ||
| ], | ||
| "expects": { | ||
| "name": "Kari", | ||
| "ageInYears": 18, | ||
| "likesIceCream": true, | ||
| "favouriteColour": null | ||
| } | ||
| }, | ||
| { | ||
| "name": "Works with a simple property query that returns a list", | ||
| "expression": [ | ||
| "jmespath", | ||
| [ | ||
| "object", | ||
| "colours", | ||
| ["list", "red", "green", "blue"] | ||
| ], | ||
| "colours" | ||
| ], | ||
| "expects": ["red", "green", "blue"] | ||
| }, | ||
| { | ||
| "name": "Works with a simple property query on a list of objects", | ||
| "expression": [ | ||
| "jmespath", | ||
| [ | ||
| "list", | ||
| ["object", "name", "Ola", "ageInYears", 30], | ||
| ["object", "name", "Kari", "ageInYears", 18], | ||
| ["object", "name", "Knut", "ageInYears", 16] | ||
| ], | ||
| "[].name" | ||
| ], | ||
| "expects": ["Ola", "Kari", "Knut"] | ||
| }, | ||
| { | ||
| "name": "Works with filtering", | ||
| "expression": [ | ||
| "jmespath", | ||
| [ | ||
| "list", | ||
| ["object", "name", "Ola", "ageInYears", 30], | ||
| ["object", "name", "Kari", "ageInYears", 18], | ||
| ["object", "name", "Knut", "ageInYears", 16] | ||
| ], | ||
| "[?ageInYears>=`18`].name" | ||
| ], | ||
| "expects": ["Ola", "Kari"] | ||
| }, | ||
| { | ||
| "name": "Works with the current-node token", | ||
| "expression": ["jmespath", ["list", "something"], "@"], | ||
| "expects": ["something"] | ||
| }, | ||
| { | ||
| "name": "Works with literal expressions", | ||
| "expression": ["jmespath", ["object"], "'Lorem ipsum'"], | ||
| "expects": "Lorem ipsum" | ||
| }, | ||
| { | ||
| "name": "Works with functions", | ||
| "expression": ["jmespath", ["object"], "abs(`-1`)"], | ||
| "expects": 1 | ||
| }, | ||
| { | ||
| "name": "Returns null when no results are found", | ||
| "expression": ["jmespath", ["object", "name", "Kari", "ageInYears", 18], "city"], | ||
| "expects": null | ||
| }, | ||
| { | ||
| "name": "Accepts string input", | ||
| "expression": ["jmespath", "This is a string", "@"], | ||
| "expects": "This is a string" | ||
| }, | ||
| { | ||
| "name": "Accepts number input", | ||
| "expression": ["jmespath", 12, "@"], | ||
| "expects": 12 | ||
| }, | ||
| { | ||
| "name": "Accepts boolean input", | ||
| "expression": ["jmespath", true, "@"], | ||
| "expects": true | ||
| }, | ||
| { | ||
| "name": "Accepts null input", | ||
| "expression": ["jmespath", null, "@"], | ||
| "expects": null | ||
| }, | ||
| { | ||
| "name": "Fails when query is invalid", | ||
| "expression": ["jmespath", ["object", "name", "Kari", "ageInYears", 18], "#"], | ||
| "expectsFailure": "Jmespath error" | ||
| }, | ||
| { | ||
| "name": "Fails when no arguments are present", | ||
| "expression": ["jmespath"], | ||
| "expectsFailure": "Expected 2 argument(s), got 0" | ||
| }, | ||
| { | ||
| "name": "Fails when the query is null", | ||
| "expression": ["jmespath", ["object"], null], | ||
| "expectsFailure": "Expected argument to be string" | ||
| }, | ||
| { | ||
| "name": "Fails when the query is neither a string nor null", | ||
| "expression": ["jmespath", ["object", "name", "Kari", "ageInYears", 18], ["object"]], | ||
| "expectsFailure": "Expected argument to be string" | ||
| } | ||
| ] | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ikke så farlig, men lurer på om det er standard at man har linjeskift før og etter taggene. Mao:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Det har du nok rett i. Jeg må si at jeg ikke er noen tilhenger av disse kommentarene i det hele tatt (navnet og signaturen til funksjonen burde være dokumenterende nok i seg selv), og disse XML-taggene gjør det bare enda mer rotete. Men jeg skjønner at dette er en konvensjon for metoder som er
public. Ved å sette alt på én linje tenkte jeg i hvert fall at vi kunne bruke litt mindre vertikal plass, men jeg ser at det heller ikke er etablert praksis.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fikset.