Alexander Shabarshov 2a7a24c9e7 Initial contribution
2025-11-03 14:43:26 +00:00

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", "")));
}
}