Skip to content

Commit aab2603

Browse files
committed
Format IN/NOT IN lists and add tests
Add formatting for SQL IN/NOT IN value lists and related tests. Introduce InPredicateCollector to collect InPredicate nodes from TSql fragments and update FormattedScriptGenerator to expand single-line comma lists into indented multi-line blocks for better readability. Add two tests (RecordingInClause, RecordingNotInClause) and their .verified.txt expectations. Update readme snippet source links to reflect new line ranges.
1 parent 0798c61 commit aab2603

6 files changed

Lines changed: 117 additions & 5 deletions

File tree

readme.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ await Verify(
168168
entries
169169
});
170170
```
171-
<sup><a href='/src/Verify.EntityFramework.Tests/CoreTests.cs#L648-L673' title='Snippet source file'>snippet source</a> | <a href='#snippet-RecordingSpecific' title='Start of snippet'>anchor</a></sup>
171+
<sup><a href='/src/Verify.EntityFramework.Tests/CoreTests.cs#L682-L707' title='Snippet source file'>snippet source</a> | <a href='#snippet-RecordingSpecific' title='Start of snippet'>anchor</a></sup>
172172
<!-- endSnippet -->
173173

174174

@@ -265,7 +265,7 @@ await data
265265

266266
await Verify();
267267
```
268-
<sup><a href='/src/Verify.EntityFramework.Tests/CoreTests.cs#L519-L542' title='Snippet source file'>snippet source</a> | <a href='#snippet-RecordingDisableForInstance' title='Start of snippet'>anchor</a></sup>
268+
<sup><a href='/src/Verify.EntityFramework.Tests/CoreTests.cs#L553-L576' title='Snippet source file'>snippet source</a> | <a href='#snippet-RecordingDisableForInstance' title='Start of snippet'>anchor</a></sup>
269269
<!-- endSnippet -->
270270

271271
<!-- snippet: CoreTests.RecordingDisabledTest.verified.txt -->
@@ -623,7 +623,7 @@ protected override void ConfigureWebHost(IWebHostBuilder webBuilder)
623623
_ => dataBuilder.Options));
624624
}
625625
```
626-
<sup><a href='/src/Verify.EntityFramework.Tests/CoreTests.cs#L602-L614' title='Snippet source file'>snippet source</a> | <a href='#snippet-EnableRecordingWithIdentifier' title='Start of snippet'>anchor</a></sup>
626+
<sup><a href='/src/Verify.EntityFramework.Tests/CoreTests.cs#L636-L648' title='Snippet source file'>snippet source</a> | <a href='#snippet-EnableRecordingWithIdentifier' title='Start of snippet'>anchor</a></sup>
627627
<!-- endSnippet -->
628628

629629
Then use the same identifier for recording:
@@ -639,7 +639,7 @@ var companies = await httpClient.GetFromJsonAsync<Company[]>("/companies");
639639

640640
var entries = Recording.Stop(testName);
641641
```
642-
<sup><a href='/src/Verify.EntityFramework.Tests/CoreTests.cs#L575-L585' title='Snippet source file'>snippet source</a> | <a href='#snippet-RecordWithIdentifier' title='Start of snippet'>anchor</a></sup>
642+
<sup><a href='/src/Verify.EntityFramework.Tests/CoreTests.cs#L609-L619' title='Snippet source file'>snippet source</a> | <a href='#snippet-RecordWithIdentifier' title='Start of snippet'>anchor</a></sup>
643643
<!-- endSnippet -->
644644

645645
The results will not be automatically included in verified file so it will have to be verified manually:
@@ -654,7 +654,7 @@ await Verify(
654654
sql = entries
655655
});
656656
```
657-
<sup><a href='/src/Verify.EntityFramework.Tests/CoreTests.cs#L587-L596' title='Snippet source file'>snippet source</a> | <a href='#snippet-VerifyRecordedCommandsWithIdentifier' title='Start of snippet'>anchor</a></sup>
657+
<sup><a href='/src/Verify.EntityFramework.Tests/CoreTests.cs#L621-L630' title='Snippet source file'>snippet source</a> | <a href='#snippet-VerifyRecordedCommandsWithIdentifier' title='Start of snippet'>anchor</a></sup>
658658
<!-- endSnippet -->
659659

660660

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
ef: {
3+
Type: ReaderExecutedAsync,
4+
HasTransaction: false,
5+
Parameters: {
6+
@ids1 (Int32): 1,
7+
@ids2 (Int32): 2,
8+
@ids3 (Int32): 4,
9+
@ids4 (Int32): 6
10+
},
11+
Text:
12+
select c.Id,
13+
c.Name
14+
from Companies as c
15+
where c.Id in (@ids1,
16+
@ids2,
17+
@ids3,
18+
@ids4)
19+
}
20+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
ef: {
3+
Type: ReaderExecutedAsync,
4+
HasTransaction: false,
5+
Parameters: {
6+
@ids1 (Int32): 1,
7+
@ids2 (Int32): 2,
8+
@ids3 (Int32): 4
9+
},
10+
Text:
11+
select c.Id,
12+
c.Name
13+
from Companies as c
14+
where c.Id not in (@ids1,
15+
@ids2,
16+
@ids3)
17+
}
18+
}

src/Verify.EntityFramework.Tests/CoreTests.cs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -510,6 +510,40 @@ await data
510510
await Verify();
511511
}
512512

513+
[Test]
514+
public async Task RecordingInClause()
515+
{
516+
var database = await DbContextBuilder.GetDatabase();
517+
var data = database.Context;
518+
519+
Recording.Start();
520+
521+
var ids = new[] { 1, 2, 4, 6 };
522+
await data
523+
.Companies
524+
.Where(_ => ids.Contains(_.Id))
525+
.ToListAsync();
526+
527+
await Verify();
528+
}
529+
530+
[Test]
531+
public async Task RecordingNotInClause()
532+
{
533+
var database = await DbContextBuilder.GetDatabase();
534+
var data = database.Context;
535+
536+
Recording.Start();
537+
538+
var ids = new[] { 1, 2, 4 };
539+
await data
540+
.Companies
541+
.Where(_ => !ids.Contains(_.Id))
542+
.ToListAsync();
543+
544+
await Verify();
545+
}
546+
513547
[Test]
514548
public async Task RecordingDisabledTest()
515549
{

src/Verify.EntityFramework/FormattedScriptGenerator.cs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,39 @@ public string GenerateScript(TSqlFragment fragment)
4646
script = string.Concat(script.AsSpan(0, pos), multiLine, script.AsSpan(pos + singleLine.Length));
4747
}
4848

49+
var inCollector = new InPredicateCollector();
50+
fragment.Accept(inCollector);
51+
52+
foreach (var inPredicate in inCollector.Predicates)
53+
{
54+
if (inPredicate.Values.Count <= 1)
55+
{
56+
continue;
57+
}
58+
59+
var values = new List<string>(inPredicate.Values.Count);
60+
foreach (var value in inPredicate.Values)
61+
{
62+
generator.GenerateScript(value, out var text);
63+
values.Add(text);
64+
}
65+
66+
var singleLine = string.Join(", ", values);
67+
68+
var pos = script.IndexOf(singleLine, StringComparison.Ordinal);
69+
if (pos == -1)
70+
{
71+
continue;
72+
}
73+
74+
var lineStart = script.LastIndexOf('\n', pos) + 1;
75+
var indent = new string(' ', pos - lineStart);
76+
77+
var multiLine = string.Join(",\n" + indent, values);
78+
79+
script = string.Concat(script.AsSpan(0, pos), multiLine, script.AsSpan(pos + singleLine.Length));
80+
}
81+
4982
return script;
5083
}
5184
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
class InPredicateCollector : TSqlFragmentVisitor
2+
{
3+
public List<InPredicate> Predicates { get; } = [];
4+
5+
public override void Visit(InPredicate node) =>
6+
Predicates.Add(node);
7+
}

0 commit comments

Comments
 (0)