444 lines
11 KiB
C#
444 lines
11 KiB
C#
/*
|
|
* dbMango
|
|
*
|
|
* Copyright 2025 Deutsche Bank AG
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
namespace Tests.Rms.Risk.Mango.Language;
|
|
|
|
[TestFixture]
|
|
public class AstToScriptTests
|
|
{
|
|
[Test]
|
|
public void AddFields()
|
|
{
|
|
var ast = new AstAggregation("CollectionName");
|
|
|
|
ast.Add(new AstPipeline([
|
|
new AstStageAddFields(
|
|
[
|
|
new AstLetExpression( new AstExpressionVariable("field1"), "FieldName"),
|
|
new AstLetExpression( new AstExpressionVariable("field2")),
|
|
]
|
|
)
|
|
]));
|
|
|
|
const string expected =
|
|
"""
|
|
FROM "CollectionName" PIPELINE {
|
|
ADD
|
|
field1 AS FieldName,
|
|
field2
|
|
}
|
|
|
|
""";
|
|
Assert.That( ast.AsText(), Is.EqualTo(expected));
|
|
}
|
|
|
|
[Test]
|
|
public void Project()
|
|
{
|
|
var ast = new AstAggregation("CollectionName");
|
|
|
|
ast.Add(new AstPipeline([
|
|
new AstStageProject(
|
|
[],
|
|
[
|
|
new AstLetExpression( new AstExpressionVariable("_id")),
|
|
new AstLetExpression( new AstExpressionVariable("field1"), "FieldName")
|
|
]
|
|
)
|
|
]));
|
|
|
|
const string expected =
|
|
"""
|
|
FROM "CollectionName" PIPELINE {
|
|
PROJECT
|
|
_id,
|
|
field1 AS FieldName
|
|
}
|
|
|
|
""";
|
|
Assert.That( ast.AsText(), Is.EqualTo(expected));
|
|
}
|
|
|
|
[Test]
|
|
public void ProjectWithComplexVar()
|
|
{
|
|
var ast = new AstAggregation("CollectionName");
|
|
|
|
ast.Add(new AstPipeline([
|
|
new AstStageProject(
|
|
[],
|
|
[
|
|
new AstLetExpression( new AstExpressionVariable("_id")),
|
|
new AstLetExpression( new AstExpressionVariable("Very.Complex.Var"), "FieldName")
|
|
]
|
|
)
|
|
]));
|
|
|
|
const string expected =
|
|
"""
|
|
FROM "CollectionName" PIPELINE {
|
|
PROJECT
|
|
_id,
|
|
$Very.Complex.Var AS FieldName
|
|
}
|
|
|
|
""";
|
|
Assert.That( ast.AsText(), Is.EqualTo(expected));
|
|
}
|
|
|
|
[Test]
|
|
public void ProjectExclude()
|
|
{
|
|
var ast = new AstAggregation("CollectionName");
|
|
|
|
ast.Add(new AstPipeline([
|
|
new AstStageProject(
|
|
[],
|
|
[
|
|
new AstLetExpression( new AstExpressionVariable("field1"))
|
|
]
|
|
, true
|
|
)
|
|
]));
|
|
|
|
const string expected =
|
|
"""
|
|
FROM "CollectionName" PIPELINE {
|
|
PROJECT EXCLUDE
|
|
field1
|
|
}
|
|
|
|
""";
|
|
Assert.That( ast.AsText(), Is.EqualTo(expected));
|
|
}
|
|
|
|
[Test]
|
|
public void Expression()
|
|
{
|
|
var ast = new AstAggregation("CollectionName");
|
|
|
|
var expr = new AstExpressionOperation(
|
|
AstExpressionOperation.OperationType.PLUS,
|
|
new AstExpressionFunctionCall("str",
|
|
[
|
|
new(null, new AstExpressionOperation(
|
|
AstExpressionOperation.OperationType.MINUS,
|
|
new AstExpressionOperation(
|
|
AstExpressionOperation.OperationType.PLUS,
|
|
new AstExpressionOperation(
|
|
AstExpressionOperation.OperationType.DIVIDE,
|
|
new AstExpressionVariable("field1"),
|
|
new AstExpressionNumber(1.234)
|
|
),
|
|
new AstExpressionNumber(5)
|
|
|
|
),
|
|
new AstExpressionFunctionCall("abs",
|
|
[
|
|
new (null, new AstExpressionNumber(-4))
|
|
]
|
|
)
|
|
))
|
|
]
|
|
),
|
|
new AstExpressionString(" miles away")
|
|
);
|
|
|
|
ast.Add(new AstPipeline([
|
|
new AstStageAddFields(
|
|
[
|
|
new AstLetExpression(expr, "Moon")
|
|
]
|
|
)
|
|
]));
|
|
|
|
const string expected =
|
|
"""
|
|
FROM "CollectionName" PIPELINE {
|
|
ADD
|
|
str( field1 / 1.234 + 5 - abs( -4 ) ) + " miles away" AS Moon
|
|
}
|
|
|
|
""";
|
|
Assert.That( ast.AsText(), Is.EqualTo(expected));
|
|
}
|
|
|
|
[Test]
|
|
public void FuncWithNamedArgs()
|
|
{
|
|
var ast = new AstAggregation("CollectionName");
|
|
|
|
var expr = new AstExpressionFunctionCall(
|
|
"dateToString",
|
|
[
|
|
new("format", new AstExpressionString("%Y-%m-%d")),
|
|
new("date", new AstExpressionVariable("field1"))
|
|
]
|
|
);
|
|
|
|
ast.Add(new AstPipeline([
|
|
new AstStageAddFields(
|
|
[
|
|
new AstLetExpression(expr, "Moon")
|
|
]
|
|
)
|
|
]));
|
|
|
|
const string expected =
|
|
"""
|
|
FROM "CollectionName" PIPELINE {
|
|
ADD
|
|
dateToString(
|
|
format: "%Y-%m-%d",
|
|
date: field1
|
|
) AS Moon
|
|
}
|
|
|
|
""";
|
|
Assert.That( ast.AsText(), Is.EqualTo(expected));
|
|
}
|
|
|
|
[Test]
|
|
public void BoolExpression()
|
|
{
|
|
var ast = new AstAggregation("CollectionName");
|
|
|
|
var expr = new AstExpressionOperation(
|
|
AstExpressionOperation.OperationType.AND,
|
|
new AstExpressionOperation(
|
|
AstExpressionOperation.OperationType.NEQ,
|
|
new AstExpressionVariable("field1"),
|
|
new AstExpressionString("Mars")
|
|
),
|
|
new AstExpressionOperation(
|
|
AstExpressionOperation.OperationType.EQ,
|
|
new AstExpressionVariable("field1"),
|
|
new AstExpressionString("Moon")
|
|
)
|
|
);
|
|
|
|
ast.Add(new AstPipeline([
|
|
new AstStageAddFields(
|
|
[
|
|
new AstLetExpression(expr, "IsMoon")
|
|
]
|
|
)
|
|
]));
|
|
|
|
const string expected =
|
|
"""
|
|
FROM "CollectionName" PIPELINE {
|
|
ADD
|
|
field1 != "Mars"
|
|
AND field1 == "Moon" AS IsMoon
|
|
}
|
|
|
|
""";
|
|
Assert.That( ast.AsText(), Is.EqualTo(expected));
|
|
}
|
|
|
|
[Test]
|
|
public void WhereTest()
|
|
{
|
|
var ast = new AstAggregation("CollectionName");
|
|
|
|
var expr = new AstExpressionOperation(
|
|
AstExpressionOperation.OperationType.AND,
|
|
new AstExpressionOperation(
|
|
AstExpressionOperation.OperationType.NEQ,
|
|
new AstExpressionVariable("field1"),
|
|
new AstExpressionString("Mars")
|
|
),
|
|
new AstExpressionOperation(
|
|
AstExpressionOperation.OperationType.EQ,
|
|
new AstExpressionVariable("field1"),
|
|
new AstExpressionString("Moon")
|
|
)
|
|
);
|
|
|
|
|
|
var whereStage = new AstStageWhere();
|
|
whereStage.Add(expr);
|
|
|
|
ast.Add(new AstPipeline([
|
|
whereStage
|
|
]));
|
|
|
|
const string expected =
|
|
"""
|
|
FROM "CollectionName" PIPELINE {
|
|
WHERE
|
|
field1 != "Mars"
|
|
AND field1 == "Moon"
|
|
}
|
|
|
|
""";
|
|
Assert.That( ast.AsText(), Is.EqualTo(expected));
|
|
|
|
}
|
|
|
|
[Test]
|
|
public void GroupByTest()
|
|
{
|
|
var ast = new AstAggregation("CollectionName");
|
|
|
|
var expr = new AstExpressionOperation(
|
|
AstExpressionOperation.OperationType.AND,
|
|
new AstExpressionOperation(
|
|
AstExpressionOperation.OperationType.NEQ,
|
|
new AstExpressionVariable("field1"),
|
|
new AstExpressionString("Mars")
|
|
),
|
|
new AstExpressionOperation(
|
|
AstExpressionOperation.OperationType.EQ,
|
|
new AstExpressionVariable("field1"),
|
|
new AstExpressionString("Moon")
|
|
)
|
|
);
|
|
|
|
|
|
var groupByStage = new AstStageGroupBy(
|
|
[
|
|
new AstLetExpression(new AstExpressionVariable("idxField1")),
|
|
new AstLetExpression(new AstExpressionVariable("idxField2"))
|
|
],
|
|
[
|
|
new AstLetExpression(expr, "IsMoon")
|
|
]
|
|
);
|
|
groupByStage.Add(expr);
|
|
|
|
ast.Add(new AstPipeline([
|
|
groupByStage
|
|
]));
|
|
|
|
const string expected =
|
|
"""
|
|
FROM "CollectionName" PIPELINE {
|
|
GROUP BY
|
|
idxField1,
|
|
idxField2
|
|
LET
|
|
field1 != "Mars"
|
|
AND field1 == "Moon" AS IsMoon
|
|
}
|
|
|
|
""";
|
|
Assert.That( ast.AsText(), Is.EqualTo(expected));
|
|
|
|
}
|
|
|
|
[Test]
|
|
public void JoinTest()
|
|
{
|
|
var ast = new AstAggregation("CollectionName");
|
|
|
|
var expr = new AstExpressionOperation(
|
|
AstExpressionOperation.OperationType.AND,
|
|
new AstExpressionOperation(
|
|
AstExpressionOperation.OperationType.NEQ,
|
|
new AstExpressionVariable("field1"),
|
|
new AstExpressionString("Mars")
|
|
),
|
|
new AstExpressionOperation(
|
|
AstExpressionOperation.OperationType.EQ,
|
|
new AstExpressionVariable("field1"),
|
|
new AstExpressionString("Moon")
|
|
)
|
|
);
|
|
|
|
|
|
var joinStage = new AstStageJoin(
|
|
"OtherCollection",
|
|
"Data",
|
|
[
|
|
new(new("myField1"), new("otherField1")),
|
|
new(new("myField2"), new("otherField2"))
|
|
],
|
|
[new AstLetExpression(expr, "IsMoon")],
|
|
new(
|
|
[
|
|
new AstStageWhere(expr)
|
|
]
|
|
)
|
|
);
|
|
|
|
ast.Add(new AstPipeline([
|
|
joinStage
|
|
]));
|
|
|
|
const string expected =
|
|
"""
|
|
FROM "CollectionName" PIPELINE {
|
|
JOIN "OtherCollection" AS Data ON
|
|
myField1 == otherField1,
|
|
myField2 == otherField2
|
|
LET
|
|
field1 != "Mars"
|
|
AND field1 == "Moon" AS IsMoon
|
|
PIPELINE {
|
|
WHERE
|
|
field1 != "Mars"
|
|
AND field1 == "Moon"
|
|
}
|
|
}
|
|
|
|
""";
|
|
Assert.That( ast.AsText(), Is.EqualTo(expected));
|
|
|
|
}
|
|
|
|
[Test]
|
|
public void DoTest()
|
|
{
|
|
var ast = new AstAggregation("CollectionName");
|
|
|
|
var doStage = new AstStageDo();
|
|
doStage.Json = JsonNode.Parse(
|
|
"""
|
|
{
|
|
"$bucket":
|
|
{
|
|
"groupBy": "$year_born"
|
|
}
|
|
}
|
|
"""
|
|
);
|
|
|
|
ast.Add(new AstPipeline([
|
|
doStage
|
|
]));
|
|
|
|
const string expected =
|
|
"""
|
|
FROM "CollectionName" PIPELINE {
|
|
DO
|
|
{
|
|
"$bucket": {
|
|
"groupBy": "$year_born"
|
|
}
|
|
}
|
|
}
|
|
|
|
""";
|
|
Assert.That( ast.AsText().Replace("\r", ""), Is.EqualTo(expected.Replace("\r", "")));
|
|
|
|
}
|
|
|
|
}
|