mirror of
https://github.com/FabInfra/capnproto-dotnetcore_Runtime.git
synced 2025-03-12 14:51:41 +01:00
242 lines
11 KiB
C#
242 lines
11 KiB
C#
using Capnp;
|
|
using Model = CapnpC.CSharp.Generator.Model;
|
|
using CodeGen = CapnpC.CSharp.Generator.CodeGen;
|
|
using CodeGeneratorRequest = CapnpC.CSharp.Generator.Schema.CodeGeneratorRequest;
|
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
|
|
namespace CapnpC.CSharp.Generator.Tests
|
|
{
|
|
[TestClass]
|
|
public class CodeGeneratorUnitTests
|
|
{
|
|
[TestMethod]
|
|
public void Test00Enumerant()
|
|
{
|
|
var model = Load("UnitTest1.capnp.bin");
|
|
Assert.AreEqual("@byte", GetTypeDef(0xc8461867c409f5d4, model).Enumerants[0].Literal);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void Test01NestedClash()
|
|
{
|
|
var (model, codegen, _) = LoadAndGenerate("UnitTest1.capnp.bin");
|
|
var structFoo = GetTypeDef(0x93db6ba5509bac24, model);
|
|
var names = codegen.GetNames();
|
|
var fieldName = names.GetCodeIdentifier(structFoo.Fields[0]).ToString();
|
|
Assert.AreEqual("Foo", structFoo.Name);
|
|
Assert.AreNotEqual(structFoo.Name, fieldName);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void Test02ForwardInheritance()
|
|
{
|
|
LoadAndGenerate("UnitTest2.capnp.bin");
|
|
}
|
|
|
|
[TestMethod]
|
|
public void Test03NonGeneratedNodeSkip()
|
|
{
|
|
LoadAndGenerate("UnitTest3.capnp.bin");
|
|
}
|
|
|
|
[TestMethod]
|
|
public void Test04MutualDependencies()
|
|
{
|
|
LoadAndGenerate("UnitTest4.capnp.bin", "UnitTest4b.capnp.bin");
|
|
}
|
|
|
|
[TestMethod]
|
|
public void Test10ImportedNamespaces()
|
|
{
|
|
var (model, codegen, _) = LoadAndGenerate("UnitTest10.capnp.bin", "UnitTest10b.capnp.bin");
|
|
var outerTypeDef = GetGeneratedFile("UnitTest10.capnp", model).NestedTypes.First();
|
|
var outerType = Model.Types.FromDefinition(outerTypeDef);
|
|
var innerType = outerTypeDef.Fields[0].Type;
|
|
var innerTypeDef = innerType.Definition;
|
|
var names = codegen.GetNames();
|
|
var outerNameSyntax = names.GetQName(outerType, outerTypeDef);
|
|
var innerNameSyntax = names.GetQName(innerType, outerTypeDef);
|
|
string[] outerNamespace = { "Foo", "Bar", "Baz" };
|
|
string[] innerNamespace = { "Foo", "Garf", "Snarf" };
|
|
CollectionAssert.AreEqual(outerNamespace, (outerTypeDef.DeclaringElement as Model.GenFile).Namespace);
|
|
CollectionAssert.AreEqual(innerNamespace, (innerType.Definition.DeclaringElement as Model.GenFile).Namespace);
|
|
string outerNSStr = String.Join('.', outerNamespace);
|
|
string innerNSStr = String.Join('.', innerNamespace);
|
|
Assert.AreEqual($"{outerNSStr}.Outer", outerNameSyntax.ToString());
|
|
Assert.AreEqual($"{innerNSStr}.Inner", innerNameSyntax.ToString());
|
|
}
|
|
|
|
[TestMethod]
|
|
public void Test11ImportedConst()
|
|
{
|
|
LoadAndGenerate("UnitTest11.capnp.bin", "UnitTest11b.capnp.bin");
|
|
}
|
|
|
|
[TestMethod]
|
|
public void Test12ConstEnum()
|
|
{
|
|
LoadAndGenerate("UnitTest12.capnp.bin");
|
|
}
|
|
|
|
[TestMethod]
|
|
public void Test13CSharpNamespace()
|
|
{
|
|
var (model, _, _) = LoadAndGenerate("UnitTest13.capnp.bin");
|
|
var outerTypeDef = GetGeneratedFile("UnitTest13.capnp", model).NestedTypes.First();
|
|
string[] outerNamespace = { "Foo", "Bar", "Baz" };
|
|
CollectionAssert.AreEqual(outerNamespace, (outerTypeDef.DeclaringElement as Model.GenFile).Namespace);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void Test14CSharpNamespacePrecedesCxxNamespace()
|
|
{
|
|
var (model, _, _) = LoadAndGenerate("UnitTest14.capnp.bin");
|
|
var outerTypeDef = GetGeneratedFile("UnitTest14.capnp", model).NestedTypes.First();
|
|
string[] outerNamespace = { "Foo", "Bar", "Baz" };
|
|
CollectionAssert.AreEqual(outerNamespace, (outerTypeDef.DeclaringElement as Model.GenFile).Namespace);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void Test15CSharpMemberNames()
|
|
{
|
|
var (_, _, code) = LoadAndGenerate("UnitTest15.capnp.bin");
|
|
try
|
|
{
|
|
Assert.IsTrue(code.Contains("CsStruct", StringComparison.Ordinal), "Generated code must contain C# struct name");
|
|
Assert.IsFalse(code.Contains("SomeStruct", StringComparison.Ordinal), "Generated code must not contain original struct name");
|
|
Assert.IsTrue(code.Contains("CsField", StringComparison.Ordinal), "Generated code must contain C# field name");
|
|
Assert.IsFalse(code.Contains("someField", StringComparison.OrdinalIgnoreCase), "Generated code must not contain original field name");
|
|
Assert.IsTrue(code.Contains("CsUnion", StringComparison.Ordinal), "Generated code must contain C# union name");
|
|
Assert.IsFalse(code.Contains("someUnion", StringComparison.OrdinalIgnoreCase), "Generated code must not contain original union name");
|
|
Assert.IsTrue(code.Contains("CsGroup", StringComparison.Ordinal), "Generated code must contain C# group name");
|
|
Assert.IsFalse(code.Contains("someGroup", StringComparison.OrdinalIgnoreCase), "Generated code must not contain original group name");
|
|
Assert.IsTrue(code.Contains("CsEnum", StringComparison.Ordinal), "Generated code must contain C# enum name");
|
|
Assert.IsFalse(code.Contains("SomeEnum", StringComparison.Ordinal), "Generated code must not contain original enum name");
|
|
Assert.IsTrue(code.Contains("CsEnumerant", StringComparison.Ordinal), "Generated code must contain C# enumerant name");
|
|
Assert.IsFalse(code.Contains("someEnumerant", StringComparison.OrdinalIgnoreCase), "Generated code must not contain original enumerant name");
|
|
Assert.IsTrue(code.Contains("CsField", StringComparison.Ordinal), "Generated code must contain C# field name");
|
|
Assert.IsFalse(code.Contains("someField", StringComparison.OrdinalIgnoreCase), "Generated code must not contain original field name");
|
|
Assert.IsTrue(code.Contains("CsInterface", StringComparison.Ordinal), "Generated code must contain C# interface name");
|
|
Assert.IsFalse(code.Contains("SomeInterface", StringComparison.Ordinal), "Generated code must not contain original interface name");
|
|
Assert.IsTrue(code.Contains("CsMethod", StringComparison.Ordinal), "Generated code must contain C# method name");
|
|
Assert.IsFalse(code.Contains("someMethod", StringComparison.OrdinalIgnoreCase), "Generated code must not contain original method name");
|
|
Assert.IsTrue(code.Contains("CsField", StringComparison.Ordinal), "Generated code must contain C# field name");
|
|
Assert.IsFalse(code.Contains("someField", StringComparison.OrdinalIgnoreCase), "Generated code must not contain original field name");
|
|
Assert.IsTrue(code.Contains("CsResult", StringComparison.Ordinal), "Generated code must contain C# method parameter name");
|
|
Assert.IsFalse(code.Contains("someResult", StringComparison.OrdinalIgnoreCase), "Generated code must not contain original method parameter name");
|
|
}
|
|
catch (AssertFailedException)
|
|
{
|
|
Console.WriteLine(code);
|
|
throw;
|
|
}
|
|
}
|
|
|
|
[TestMethod]
|
|
public void Test20AnnotationAndConst()
|
|
{
|
|
LoadAndGenerate("UnitTest20.capnp.bin");
|
|
}
|
|
|
|
[TestMethod]
|
|
public void Test30SchemaCapnp()
|
|
{
|
|
LoadAndGenerate("schema-with-offsets.capnp.bin");
|
|
}
|
|
|
|
[TestMethod]
|
|
public void Issue45()
|
|
{
|
|
var input = CodeGeneratorSteps.LoadResource("Issue45.capnp.bin");
|
|
using (input)
|
|
{
|
|
var frame = Framing.ReadSegments(input);
|
|
var ds = DeserializerState.CreateRoot(frame);
|
|
var cgr = CapnpSerializable.Create<CodeGeneratorRequest>(ds);
|
|
Assert.IsTrue(cgr.Nodes.Count > 0);
|
|
}
|
|
|
|
}
|
|
|
|
static (Model.SchemaModel, CodeGen.CodeGenerator, string) LoadAndGenerate(params string[] inputNames)
|
|
{
|
|
Model.SchemaModel firstModel = null;
|
|
CodeGen.CodeGenerator firstCodeGen = null;
|
|
|
|
Model.SchemaModel LocalLoad(string name)
|
|
{
|
|
var model = Load(name);
|
|
firstModel = firstModel ?? model;
|
|
return model;
|
|
}
|
|
|
|
CodeGen.CodeGenerator CreateCodeGen(Model.SchemaModel model)
|
|
{
|
|
var codegen = new CodeGen.CodeGenerator(model, new CodeGen.GeneratorOptions());
|
|
firstCodeGen = firstCodeGen ?? codegen;
|
|
return codegen;
|
|
}
|
|
|
|
var codes = (
|
|
from name in inputNames
|
|
let model = LocalLoad(name)
|
|
let codegen = CreateCodeGen(model)
|
|
from file in model.FilesToGenerate
|
|
select codegen.Transform(file)).ToArray();
|
|
|
|
Assert.AreEqual(
|
|
Util.InlineAssemblyCompiler.CompileSummary.Success,
|
|
Util.InlineAssemblyCompiler.TryCompileCapnp(
|
|
Microsoft.CodeAnalysis.NullableContextOptions.Disable,
|
|
codes),
|
|
"Compilation was not successful with no warnings");
|
|
|
|
return (firstModel, firstCodeGen, codes[0]);
|
|
}
|
|
|
|
static Model.GenFile GetGeneratedFile(string name, Model.SchemaModel model)
|
|
{
|
|
var file = model.FilesToGenerate.SingleOrDefault(f => f.Name.EndsWith(name));
|
|
Assert.IsNotNull(file, $"Could not find '{name}' in generated files");
|
|
return file;
|
|
}
|
|
|
|
static Model.TypeDefinition GetTypeDef(ulong id, Model.SchemaModel model)
|
|
{
|
|
foreach (var defs in model.FilesToGenerate.Select(f => f.NestedTypes))
|
|
{
|
|
if (GetTypeDef(id, defs) is Model.TypeDefinition def) return def;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
static Model.TypeDefinition GetTypeDef(ulong id, IEnumerable<Model.TypeDefinition> defs)
|
|
{
|
|
foreach (var def in defs)
|
|
{
|
|
if (def.Id == id) return def;
|
|
var sub = GetTypeDef(id, def.NestedTypes);
|
|
if (sub != null) return sub;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
static Model.SchemaModel Load(string inputName)
|
|
{
|
|
WireFrame segments;
|
|
var input = CodeGeneratorSteps.LoadResource(inputName);
|
|
using (input)
|
|
{
|
|
segments = Framing.ReadSegments(input);
|
|
}
|
|
var dec = DeserializerState.CreateRoot(segments);
|
|
var reader = CodeGeneratorRequest.READER.create(dec);
|
|
var model = Model.SchemaModel.Create(reader);
|
|
return model;
|
|
}
|
|
}
|
|
}
|