Skip to content

Commit b509e83

Browse files
committed
Merge branch 'main' into type-constraints
# Conflicts: # test/GqlPlus.Converter.Json.ComponentTests/Sample/SampleJsonTests/Objects/generic-dual+dual.verified.json # test/GqlPlus.Converter.Json.ComponentTests/Sample/SampleJsonTests/Objects/generic-dual+input.verified.json # test/GqlPlus.Converter.Json.ComponentTests/Sample/SampleJsonTests/Objects/generic-dual+output.verified.json # test/GqlPlus.Converter.Json.ComponentTests/Sample/SampleJsonTests/Objects/generic-param+dual.verified.json # test/GqlPlus.Converter.Json.ComponentTests/Sample/SampleJsonTests/Objects/generic-param+input.verified.json # test/GqlPlus.Converter.Json.ComponentTests/Sample/SampleJsonTests/Objects/generic-param+output.verified.json # test/GqlPlus.Converter.Json.ComponentTests/Sample/SampleJsonTests/constraint-alt-dual+input.verified.json # test/GqlPlus.Converter.Json.ComponentTests/Sample/SampleJsonTests/constraint-alt-dual+output.verified.json # test/GqlPlus.Converter.Json.ComponentTests/Sample/SampleJsonTests/constraint-field-dual+dual.verified.json # test/GqlPlus.Converter.Json.ComponentTests/Sample/SampleJsonTests/constraint-field-obj+dual.verified.json # test/GqlPlus.Converter.Json.ComponentTests/Sample/SampleJsonTests/constraint-field-obj+input.verified.json # test/GqlPlus.Converter.Json.ComponentTests/Sample/SampleJsonTests/constraint-field-obj+output.verified.json # test/GqlPlus.Converter.Json.ComponentTests/Sample/SampleJsonTests/generic-dual+dual.verified.json # test/GqlPlus.Converter.Json.ComponentTests/Sample/SampleJsonTests/generic-dual+input.verified.json # test/GqlPlus.Converter.Json.ComponentTests/Sample/SampleJsonTests/generic-dual+output.verified.json # test/GqlPlus.Converter.Json.ComponentTests/Sample/SampleJsonTests/generic-param+dual.verified.json # test/GqlPlus.Converter.Json.ComponentTests/Sample/SampleJsonTests/generic-param+input.verified.json # test/GqlPlus.Converter.Json.ComponentTests/Sample/SampleJsonTests/generic-param+output.verified.json # test/GqlPlus.Converter.Yaml.ComponentTests/Sample/SampleYamlTests/Objects/generic-dual+dual.verified.txt # test/GqlPlus.Converter.Yaml.ComponentTests/Sample/SampleYamlTests/Objects/generic-dual+input.verified.txt # test/GqlPlus.Converter.Yaml.ComponentTests/Sample/SampleYamlTests/Objects/generic-dual+output.verified.txt # test/GqlPlus.Converter.Yaml.ComponentTests/Sample/SampleYamlTests/Objects/generic-param+dual.verified.txt # test/GqlPlus.Converter.Yaml.ComponentTests/Sample/SampleYamlTests/Objects/generic-param+input.verified.txt # test/GqlPlus.Converter.Yaml.ComponentTests/Sample/SampleYamlTests/Objects/generic-param+output.verified.txt # test/GqlPlus.Modeller.ComponentTests/Sample/SampleLinesTests/Objects/generic-dual+dual.verified.txt # test/GqlPlus.Modeller.ComponentTests/Sample/SampleLinesTests/Objects/generic-dual+input.verified.txt # test/GqlPlus.Modeller.ComponentTests/Sample/SampleLinesTests/Objects/generic-dual+output.verified.txt # test/GqlPlus.Modeller.ComponentTests/Sample/SampleLinesTests/Objects/generic-param+dual.verified.txt # test/GqlPlus.Modeller.ComponentTests/Sample/SampleLinesTests/Objects/generic-param+input.verified.txt # test/GqlPlus.Modeller.ComponentTests/Sample/SampleLinesTests/Objects/generic-param+output.verified.txt # test/GqlPlus.Parser.ComponentTests/Schema/MergeSchemaTests/_object-param-constraint.verified.txt # test/GqlPlus.Parser.ComponentTests/Schema/MergeSchemaTests/_object-param-dup.verified.txt # test/GqlPlus.Parser.ComponentTests/Schema/MergeSchemaTests/object-param-constraint+dual.verified.txt # test/GqlPlus.Parser.ComponentTests/Schema/MergeSchemaTests/object-param-constraint+input.verified.txt # test/GqlPlus.Parser.ComponentTests/Schema/MergeSchemaTests/object-param-constraint+output.verified.txt # test/GqlPlus.Parser.ComponentTests/Schema/MergeSchemaTests/object-param-dup+dual.verified.txt # test/GqlPlus.Parser.ComponentTests/Schema/MergeSchemaTests/object-param-dup+input.verified.txt # test/GqlPlus.Parser.ComponentTests/Schema/MergeSchemaTests/object-param-dup+output.verified.txt
2 parents e60399c + c7ab193 commit b509e83

File tree

975 files changed

+314
-481
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

975 files changed

+314
-481
lines changed

Diff for: test/GqlPlus.ComponentTestBase/SampleChecks.cs

+119-2
Original file line numberDiff line numberDiff line change
@@ -85,12 +85,16 @@ protected async Task CheckErrors(string category, string directory, string file,
8585
() => extra.ShouldBeEmpty("Extra errors"));
8686
}
8787

88-
protected VerifySettings CustomSettings(string category, string group, string file)
88+
protected VerifySettings CustomSettings(string category, string group, string file, string section = "")
8989
{
9090
VerifySettings settings = new();
9191
settings.ScrubEmptyLines();
92-
settings.UseDirectory($"{category}{group}Tests");
9392
settings.UseFileName(file);
93+
if (string.IsNullOrWhiteSpace(section)) {
94+
settings.UseDirectory($"{category}{group}Tests");
95+
} else {
96+
settings.UseDirectory($"{category}{group}Tests/{section}");
97+
}
9498

9599
return settings.CheckAutoVerify();
96100
}
@@ -100,4 +104,117 @@ protected static async Task<string> ReadFile(string file, string extn, params st
100104

101105
protected static async Task<string> ReadSchema(string schema, params string[] dirs)
102106
=> await ReadFile(schema, "graphql+", ["Schema", .. dirs]);
107+
108+
protected static bool IsObjectInput(string input)
109+
=> input is not null && input.Contains("object ", StringComparison.Ordinal);
110+
111+
private static string PascalCase(string? input)
112+
=> string.Concat(TitleWords(input).Select(s => Abbreviations.TryGetValue(s, out string? abbr) ? abbr : s));
113+
114+
private static string CamelCase(string? input)
115+
=> string.Concat(TitleWords(input)
116+
.Select(s => Abbreviations.TryGetValue(s, out string? abbr) ? abbr : s)
117+
.Select((s, i) => i > 0 ? s : s.ToLowerInvariant()));
118+
119+
public static readonly (string, string)[] Replacements = [("dual", "Dual"), ("input", "Inp"), ("output", "Outp")];
120+
121+
protected static string ReplaceName(string? input, string testName)
122+
=> input is null ? ""
123+
: input
124+
.Replace("name", CamelCase(testName), StringComparison.InvariantCulture)
125+
.Replace("Name", PascalCase(testName), StringComparison.InvariantCulture);
126+
127+
protected static string ReplaceObject(string? input, string testName, string objectReplace, string objReplace)
128+
=> input is null ? ""
129+
: input
130+
.Replace("object", objectReplace, StringComparison.InvariantCulture)
131+
.Replace("Obj", objReplace, StringComparison.InvariantCulture)
132+
.Replace("name", CamelCase(testName), StringComparison.InvariantCulture)
133+
.Replace("Name", PascalCase(testName), StringComparison.InvariantCulture);
134+
135+
protected static IEnumerable<string> ReplaceValue(string input, string testName)
136+
=> input
137+
.ThrowIfNull()
138+
.Contains("object ", StringComparison.Ordinal)
139+
? Replacements.Select(r => ReplaceObject(input, testName, r.Item1, r.Item2))
140+
: [ReplaceName(input, testName)];
141+
142+
protected static async Task ReplaceFile(string testDirectory, string testName, Action<string, string, string> action)
143+
{
144+
ArgumentNullException.ThrowIfNull(action);
145+
string input = await ReadSchema(testName, testDirectory);
146+
147+
if (IsObjectInput(input)) {
148+
action.ShouldSatisfyAllConditions(
149+
() => {
150+
foreach ((string label, string abbr) in Replacements) {
151+
action(ReplaceObject(input, abbr, label, abbr), testDirectory, testName + "+" + label);
152+
}
153+
});
154+
} else {
155+
action(ReplaceName(input, testName), testDirectory, testName);
156+
}
157+
}
158+
159+
protected static async Task ReplaceFileAsync(string testDirectory, string testName, Func<string, string, string, Task> action)
160+
{
161+
ArgumentNullException.ThrowIfNull(action);
162+
string input = await ReadSchema(testName, testDirectory);
163+
164+
if (IsObjectInput(input)) {
165+
await WhenAll([.. Replacements
166+
.Select(r => action(ReplaceObject(input, testName, r.Item1, r.Item2), testDirectory, testName + "+" + r.Item1))]);
167+
} else {
168+
await action(ReplaceName(input, testName), testDirectory, testName);
169+
}
170+
}
171+
172+
protected async Task<IEnumerable<string>> SchemaValidDataAll()
173+
{
174+
IEnumerable<Task<IEnumerable<string>>> tasks = SchemaValidData
175+
.Files
176+
.SelectMany(kv => kv.Value.Select(file => (file, dir: kv.Key)))
177+
.Select(async p => ReplaceValue(await ReadSchema(p.file, p.dir), p.file));
178+
179+
return (await Task.WhenAll(tasks))
180+
.SelectMany(i => i);
181+
}
182+
183+
protected async Task<IEnumerable<string>> SchemaValidDataGroup(string group)
184+
{
185+
IEnumerable<Task<IEnumerable<string>>> tasks = SchemaValidData
186+
.Files[group]
187+
.Select(async file => ReplaceValue(await ReadSchema(file, group), file));
188+
189+
return (await Task.WhenAll(tasks))
190+
.SelectMany(i => i);
191+
}
192+
193+
protected static async Task<IEnumerable<string>> ReplaceSchemaKeys(string group)
194+
{
195+
IEnumerable<Task<(string input, string file)>> tasks = SchemaValidData
196+
.Files[group]
197+
.Select(async file => (input: await ReadSchema(file, group), file));
198+
199+
return (await Task.WhenAll(tasks))
200+
.SelectMany(p => IsObjectInput(p.input)
201+
? Replacements.Select(r => p.file + "+" + r.Item1)
202+
: [p.file])
203+
.Order();
204+
}
205+
206+
protected static async Task WhenAll(params Task[] tasks)
207+
{
208+
Task all = Task.WhenAll(tasks);
209+
210+
try {
211+
await all;
212+
} catch (Exception) {
213+
if (all.Exception is not null) {
214+
throw all.Exception;
215+
}
216+
217+
throw;
218+
}
219+
}
103220
}

Diff for: test/GqlPlus.ComponentTestBase/SampleSchemaChecks.cs

+2-102
Original file line numberDiff line numberDiff line change
@@ -11,115 +11,15 @@ Parser<IGqlpSchema>.D schemaParser
1111
{
1212
private readonly Parser<IGqlpSchema>.L _schemaParser = schemaParser;
1313

14-
protected IResult<IGqlpSchema> Parse(string schema, string label)
14+
public IResult<IGqlpSchema> Parse(string schema, string label)
1515
{
1616
Tokenizer tokens = new(schema);
1717
return _schemaParser.Parse(tokens, label);
1818
}
1919

20-
protected async Task<IGqlpSchema> ParseSample(string label, string sample, params string[] dirs)
20+
public async Task<IGqlpSchema> ParseSample(string label, string sample, params string[] dirs)
2121
{
2222
string schema = await ReadSchema(sample, dirs);
2323
return Parse(schema, label).Required();
2424
}
25-
26-
protected static bool IsObjectInput(string input)
27-
=> input is not null && input.Contains("object ", StringComparison.Ordinal);
28-
29-
private static string PascalCase(string? input)
30-
=> string.Concat(TitleWords(input).Select(s => Abbreviations.TryGetValue(s, out string? abbr) ? abbr : s));
31-
32-
private static string CamelCase(string? input)
33-
=> string.Concat(TitleWords(input)
34-
.Select(s => Abbreviations.TryGetValue(s, out string? abbr) ? abbr : s)
35-
.Select((s, i) => i > 0 ? s : s.ToLowerInvariant()));
36-
37-
public static readonly (string, string)[] Replacements = [("dual", "Dual"), ("input", "Inp"), ("output", "Outp")];
38-
39-
protected static string ReplaceName(string? input, string testName)
40-
=> input is null ? ""
41-
: input
42-
.Replace("name", CamelCase(testName), StringComparison.InvariantCulture)
43-
.Replace("Name", PascalCase(testName), StringComparison.InvariantCulture);
44-
45-
protected static string ReplaceObject(string? input, string testName, string objectReplace, string objReplace)
46-
=> input is null ? ""
47-
: input
48-
.Replace("object", objectReplace, StringComparison.InvariantCulture)
49-
.Replace("Obj", objReplace, StringComparison.InvariantCulture)
50-
.Replace("name", CamelCase(testName), StringComparison.InvariantCulture)
51-
.Replace("Name", PascalCase(testName), StringComparison.InvariantCulture);
52-
53-
protected static IEnumerable<string> ReplaceValue(string input, string testName)
54-
=> input
55-
.ThrowIfNull()
56-
.Contains("object ", StringComparison.Ordinal)
57-
? Replacements.Select(r => ReplaceObject(input, testName, r.Item1, r.Item2))
58-
: [ReplaceName(input, testName)];
59-
60-
protected static async Task ReplaceFile(string testDirectory, string testName, Action<string, string, string> action)
61-
{
62-
ArgumentNullException.ThrowIfNull(action);
63-
string input = await ReadSchema(testName, testDirectory);
64-
65-
if (IsObjectInput(input)) {
66-
action.ShouldSatisfyAllConditions(
67-
() => {
68-
foreach ((string label, string abbr) in Replacements) {
69-
action(ReplaceObject(input, abbr, label, abbr), testDirectory, testName + "+" + label);
70-
}
71-
});
72-
} else {
73-
action(ReplaceName(input, testName), testDirectory, testName);
74-
}
75-
}
76-
77-
protected static async Task ReplaceFileAsync(string testDirectory, string testName, Func<string, string, string, Task> action)
78-
{
79-
ArgumentNullException.ThrowIfNull(action);
80-
string input = await ReadSchema(testName, testDirectory);
81-
82-
if (IsObjectInput(input)) {
83-
await WhenAll([.. Replacements
84-
.Select(r => action(ReplaceObject(input, testName, r.Item1, r.Item2), testDirectory, testName + "+" + r.Item1))]);
85-
} else {
86-
await action(ReplaceName(input, testName), testDirectory, testName);
87-
}
88-
}
89-
90-
protected async Task<IEnumerable<string>> SchemaValidDataAll()
91-
{
92-
IEnumerable<Task<IEnumerable<string>>> tasks = SchemaValidData
93-
.Files
94-
.SelectMany(kv => kv.Value.Select(file => (file, dir: kv.Key)))
95-
.Select(async p => ReplaceValue(await ReadSchema(p.file, p.dir), p.file));
96-
97-
return (await Task.WhenAll(tasks))
98-
.SelectMany(i => i);
99-
}
100-
101-
protected async Task<IEnumerable<string>> SchemaValidDataGroup(string group)
102-
{
103-
IEnumerable<Task<IEnumerable<string>>> tasks = SchemaValidData
104-
.Files[group]
105-
.Select(async file => ReplaceValue(await ReadSchema(file, group), file));
106-
107-
return (await Task.WhenAll(tasks))
108-
.SelectMany(i => i);
109-
}
110-
111-
protected static async Task WhenAll(params Task[] tasks)
112-
{
113-
Task all = Task.WhenAll(tasks);
114-
115-
try {
116-
await all;
117-
} catch (Exception) {
118-
if (all.Exception is not null) {
119-
throw all.Exception;
120-
}
121-
122-
throw;
123-
}
124-
}
12525
}

Diff for: test/GqlPlus.ComponentTestBase/SchemaDataBase.cs

-13
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,6 @@ protected static IEnumerable<string> ReplaceKeys(IDictionary<string, string> inp
1717
: [k])
1818
.Order();
1919

20-
protected static async Task<IEnumerable<string>> ReplaceSchemaKeys(string group)
21-
{
22-
IEnumerable<Task<(string input, string file)>> tasks = SchemaValidData
23-
.Files[group]
24-
.Select(async file => (input: await ReadSchema(file, group), file));
25-
26-
return (await Task.WhenAll(tasks))
27-
.SelectMany(p => IsObjectInput(p.input)
28-
? Replacements.Select(r => p.file + "+" + r.Item1)
29-
: [p.file])
30-
.Order();
31-
}
32-
3320
protected static IEnumerable<string> ReplaceValues(IDictionary<string, string> inputs)
3421
=> inputs
3522
.ThrowIfNull()
Original file line numberDiff line numberDiff line change
@@ -1,86 +1,11 @@
1-
using GqlPlus.Abstractions.Schema;
2-
using GqlPlus.Convert;
3-
using GqlPlus.Merging;
4-
using GqlPlus.Parsing;
5-
using GqlPlus.Result;
1+
using GqlPlus.Convert;
62

73
namespace GqlPlus.Sample;
84

95
public class SchemaJsonTests(
10-
Parser<IGqlpSchema>.D schemaParser,
11-
IMerge<IGqlpSchema> schemaMerger,
12-
IModelAndRender schemaRenderer
13-
) : SchemaDataBase(schemaParser)
6+
ISchemaVerifyChecks checks
7+
) : TestSchemaVerify(checks)
148
{
15-
[Fact]
16-
public async Task Json_All()
17-
=> await Verify_Model(await SchemaValidDataAll(), "!ALL");
18-
19-
[Theory]
20-
[ClassData(typeof(SchemaValidData))]
21-
public async Task Json_Groups(string group)
22-
=> await Verify_Model(await SchemaValidDataGroup(group), "!" + group);
23-
24-
[Theory]
25-
[ClassData(typeof(SamplesSchemaMergesData))]
26-
public async Task Json_Merges(string model)
27-
=> await ReplaceFileAsync("Merges", model, Verify_Model);
28-
29-
[Theory]
30-
[ClassData(typeof(SamplesSchemaObjectsData))]
31-
public async Task Json_Objects(string model)
32-
=> await ReplaceFileAsync("Objects", model, Verify_Model);
33-
34-
[Theory]
35-
[ClassData(typeof(SamplesSchemaGlobalsData))]
36-
public async Task Json_Globals(string global)
37-
=> await ReplaceFileAsync("Globals", global, Verify_Model);
38-
39-
[Theory]
40-
[ClassData(typeof(SamplesSchemaSimpleData))]
41-
public async Task Json_Simple(string simple)
42-
=> await ReplaceFileAsync("Simple", simple, Verify_Model);
43-
44-
[Theory]
45-
[ClassData(typeof(SamplesSchemaData))]
46-
public async Task JsonSchema(string sample)
47-
{
48-
IGqlpSchema ast = await ParseSample("Schema", sample);
49-
50-
Structured result = ModelAsts([ast]);
51-
52-
await Verify(result.ToJson(), "json", CustomSettings("Schema", "Json", sample));
53-
}
54-
55-
[Theory]
56-
[ClassData(typeof(SamplesSchemaSpecificationData))]
57-
public async Task Json_Spec(string sample)
58-
{
59-
IGqlpSchema ast = await ParseSample("Spec", sample, "Specification");
60-
61-
Structured result = ModelAsts([ast]);
62-
63-
await Verify(result.ToJson(), "json", CustomSettings("Spec", "Json", sample));
64-
}
65-
66-
private async Task Verify_Model(string input, string testDirectory, string test)
67-
=> await Verify_Model([input], test);
68-
69-
private async Task Verify_Model(IEnumerable<string> inputs, string test)
70-
{
71-
IEnumerable<IGqlpSchema> asts = inputs.Select(input => Parse(input, "Sample").Required());
72-
73-
Structured result = ModelAsts(asts);
74-
75-
await Verify(result.ToJson(), "json", CustomSettings("Sample", "Json", test));
76-
}
77-
78-
private Structured ModelAsts(IEnumerable<IGqlpSchema> asts)
79-
{
80-
IGqlpSchema schema = schemaMerger.Merge(asts).First();
81-
82-
Structured result = schemaRenderer.RenderAst(schema, schemaRenderer.WithBuiltIns());
83-
84-
return result;
85-
}
9+
protected override Task VerifyResult(Structured result, string label, string test, string testDirectory)
10+
=> Verify(result.ToJson(), "json", CustomSettings(label, "Json", test, testDirectory));
8611
}

0 commit comments

Comments
 (0)