-
Notifications
You must be signed in to change notification settings - Fork 113
/
Copy pathCompletionTests.cs
129 lines (110 loc) · 5.46 KB
/
CompletionTests.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
using System.Linq;
using System.Threading.Tasks;
using CSharpRepl.PrettyPromptConfig;
using CSharpRepl.Services;
using CSharpRepl.Services.Roslyn;
using PrettyPrompt.Documents;
using Xunit;
namespace CSharpRepl.Tests;
[Collection(nameof(RoslynServices))]
public class CompletionTests : IAsyncLifetime, IClassFixture<RoslynServicesFixture>
{
private readonly RoslynServices services;
private readonly CSharpReplPromptCallbacks promptCallbacks;
public CompletionTests(RoslynServicesFixture fixture)
{
var (console, _) = FakeConsole.CreateStubbedOutput();
this.services = fixture.RoslynServices;
promptCallbacks = new CSharpReplPromptCallbacks(console, services, new Configuration());
}
public Task InitializeAsync() => services.WarmUpAsync([]);
public Task DisposeAsync() => Task.CompletedTask;
[Fact]
public async Task Complete_GivenCode_ReturnsCompletions()
{
var completions = await this.services.CompleteAsync("Console.Writ", 12);
var writelines = completions
.Where(c => c.Item.DisplayText.StartsWith("Write"))
.ToList();
Assert.Equal("Write", writelines[0].Item.DisplayText);
Assert.Equal("WriteLine", writelines[1].Item.DisplayText);
var writeDescription = await writelines[0].GetDescriptionAsync(cancellationToken: default);
Assert.Contains("Writes the text representation of the specified", writeDescription.Text);
var writeLineDescription = await writelines[1].GetDescriptionAsync(cancellationToken: default);
Assert.Contains("Writes the current line terminator to the standard output", writeLineDescription.Text);
}
[Fact]
public async Task Complete_GivenLinq_ReturnsCompletions()
{
// LINQ tends to be a good canary for whether or not our reference / implementation assemblies are correct.
var completions = await this.services.CompleteAsync("new[] { 1, 2, 3 }.Wher", 21);
var whereCompletion = completions.SingleOrDefault(c => c.Item.DisplayText.StartsWith("Where"));
Assert.NotNull(whereCompletion);
Assert.Equal("Where", whereCompletion.Item.DisplayText);
var whereDescription = await whereCompletion.GetDescriptionAsync(cancellationToken: default);
Assert.Contains("Filters a sequence of values based on a predicate", whereDescription.Text);
}
/// <summary>
/// https://github.com/waf/CSharpRepl/issues/4
/// </summary>
[Fact]
public async Task Complete_SyntaxHighlight_CachesAreIsolated()
{
// type "c" which triggers completion at index 1, and is cached
var completions = await this.services.CompleteAsync("c", 1);
// next, type the number 1, which could collide with the previous cached value if the caches
// aren't isolated, resulting in an exception
var highlights = await this.services.SyntaxHighlightAsync("c1");
Assert.NotEmpty(completions);
Assert.NotEmpty(highlights);
}
/// <summary>
/// https://github.com/waf/CSharpRepl/issues/65
/// </summary>
[Fact]
public async Task Complete_GetDescriptionForShorterCompletion()
{
var completions = await this.services.CompleteAsync("datetime", 8);
var arrayCompletion = completions.SingleOrDefault(c => c.Item.DisplayText == "Array");
Assert.NotNull(arrayCompletion);
var arrayDescription = await arrayCompletion.GetDescriptionAsync(cancellationToken: default);
Assert.Contains("Provides methods for creating, manipulating, searching, and sorting arrays", arrayDescription.Text);
}
/// <summary>
/// https://github.com/waf/CSharpRepl/issues/92
/// </summary>
[Fact]
public async Task Complete_GetDescriptionAfterDot()
{
var completions = await this.services.CompleteAsync("\"\".Where()", 3);
var whereCompletion = completions.SingleOrDefault(c => c.Item.DisplayText == "Where");
Assert.NotNull(whereCompletion);
var whereDescription = await whereCompletion.GetDescriptionAsync(cancellationToken: default);
Assert.Contains("Filters a sequence of values based on a predicate", whereDescription.Text);
}
/// <summary>
/// https://github.com/waf/CSharpRepl/issues/215
/// </summary>
[Theory]
[InlineData("fil", "file", "File", "FileAccess")]
[InlineData("Fil", "File", "FileAccess", "FileAttributes")]
[InlineData("con", "const", "ConcurrentExclusiveSchedulerPair", "ConfigureAwaitOptions", "Console")]
[InlineData("Con", "ConcurrentExclusiveSchedulerPair", "ConfigureAwaitOptions", "Console", "ConsoleCancelEventArgs")]
[InlineData("en", "enum", "Encoder")]
[InlineData("enu", "enum", "Enum", "Enumerable")]
[InlineData("Enu", "Enum", "Enumerable")]
public async Task Complete_ItemsFilteringAndOrder(string text, params string[] expectedItems)
{
var caret = text.Length;
var span = new TextSpan(0, text.Length);
var completions = (await this.services.CompleteAsync(text, caret))
.OrderByDescending(i => promptCallbacks.CreatePrettyPromptCompletionItem(i).GetCompletionItemPriority(text, caret, span));
for (int i = 0; i < expectedItems.Length; i++)
{
Assert.Equal(expectedItems[i], completions.ElementAt(i).Item.DisplayText);
}
}
}