Skip to content

Commit 1524842

Browse files
Copilotsebastienros
andcommitted
Add tests for intermediate identifiers with trailing question marks
Co-authored-by: sebastienros <1165805+sebastienros@users.noreply.github.com>
1 parent 82f1d28 commit 1524842

File tree

1 file changed

+70
-0
lines changed

1 file changed

+70
-0
lines changed

Fluid.Tests/TrailingQuestionTests.cs

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,5 +221,75 @@ public async Task ShouldRenderTrailingQuestionWithFilters()
221221
var result = await template.RenderAsync(context);
222222
Assert.Equal("HELLO", result);
223223
}
224+
225+
[Fact]
226+
public void ShouldSupportTrailingQuestionOnIntermediateIdentifiers()
227+
{
228+
var parser = new FluidParser(new FluidParserOptions { AllowTrailingQuestion = true });
229+
parser.TryParse("{{ a?.b.c }}", out var template, out var errors);
230+
231+
var statements = ((FluidTemplate)template).Statements;
232+
var outputStatement = statements[0] as OutputStatement;
233+
Assert.NotNull(outputStatement);
234+
235+
var memberExpression = outputStatement.Expression as MemberExpression;
236+
Assert.NotNull(memberExpression);
237+
Assert.Equal(3, memberExpression.Segments.Count);
238+
239+
var firstSegment = memberExpression.Segments[0] as IdentifierSegment;
240+
Assert.NotNull(firstSegment);
241+
Assert.Equal("a", firstSegment.Identifier); // Should NOT contain '?'
242+
243+
var secondSegment = memberExpression.Segments[1] as IdentifierSegment;
244+
Assert.NotNull(secondSegment);
245+
Assert.Equal("b", secondSegment.Identifier);
246+
247+
var thirdSegment = memberExpression.Segments[2] as IdentifierSegment;
248+
Assert.NotNull(thirdSegment);
249+
Assert.Equal("c", thirdSegment.Identifier);
250+
}
251+
252+
[Fact]
253+
public async Task ShouldResolveIntermediateIdentifiersWithTrailingQuestion()
254+
{
255+
var parser = new FluidParser(new FluidParserOptions { AllowTrailingQuestion = true });
256+
parser.TryParse("{{ obj?.nested.value }}", out var template, out var errors);
257+
258+
var context = new TemplateContext();
259+
var nested = new { value = "test" };
260+
var obj = new { nested };
261+
context.Options.MemberAccessStrategy.Register(nested.GetType());
262+
context.Options.MemberAccessStrategy.Register(obj.GetType());
263+
context.SetValue("obj", obj);
264+
265+
var result = await template.RenderAsync(context);
266+
Assert.Equal("test", result);
267+
}
268+
269+
[Theory]
270+
[InlineData("{{ a?.b.c }}", new[] { "a", "b", "c" })]
271+
[InlineData("{{ a.b?.c }}", new[] { "a", "b", "c" })]
272+
[InlineData("{{ a?.b?.c }}", new[] { "a", "b", "c" })]
273+
[InlineData("{{ a?.b?.c? }}", new[] { "a", "b", "c" })]
274+
public void ShouldStripTrailingQuestionFromAllSegments(string template, string[] expectedIdentifiers)
275+
{
276+
var parser = new FluidParser(new FluidParserOptions { AllowTrailingQuestion = true });
277+
parser.TryParse(template, out var parsedTemplate, out var errors);
278+
279+
var statements = ((FluidTemplate)parsedTemplate).Statements;
280+
var outputStatement = statements[0] as OutputStatement;
281+
Assert.NotNull(outputStatement);
282+
283+
var memberExpression = outputStatement.Expression as MemberExpression;
284+
Assert.NotNull(memberExpression);
285+
Assert.Equal(expectedIdentifiers.Length, memberExpression.Segments.Count);
286+
287+
for (int i = 0; i < expectedIdentifiers.Length; i++)
288+
{
289+
var segment = memberExpression.Segments[i] as IdentifierSegment;
290+
Assert.NotNull(segment);
291+
Assert.Equal(expectedIdentifiers[i], segment.Identifier);
292+
}
293+
}
224294
}
225295
}

0 commit comments

Comments
 (0)