Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
126 changes: 122 additions & 4 deletions tests/generator-Tests/Unit-Tests/XmlApiImporterTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,35 @@ public void CreateClass_EnsureValidName ()
Assert.AreEqual ("_3", klass.Name);
}

[Test]
public void CreateClass_CorrectApiSince ()
{
var xml = XDocument.Parse ("<package name='com.example.test' jni-name='com/example/test'><class name='myclass' api-since='7' /></package>");
var klass = XmlApiImporter.CreateClass (xml.Root, xml.Root.Element ("class"), opt);

Assert.AreEqual (7, klass.ApiAvailableSince);
}

[Test]
public void CreateClass_CorrectApiSinceFromPackage ()
{
// Make sure we inherit it from <package>.
var xml = XDocument.Parse ("<package name='com.example.test' jni-name='com/example/test' api-since='7'><class name='myclass' /></package>");
var klass = XmlApiImporter.CreateClass (xml.Root, xml.Root.Element ("class"), opt);

Assert.AreEqual (7, klass.ApiAvailableSince);
}

[Test]
public void CreateClass_CorrectApiSinceOverridePackage ()
{
// Make sure we inherit it from <package>.
var xml = XDocument.Parse ("<package name='com.example.test' jni-name='com/example/test' api-since='7'><class name='myclass' api-since='9' /></package>");
var klass = XmlApiImporter.CreateClass (xml.Root, xml.Root.Element ("class"), opt);

Assert.AreEqual (9, klass.ApiAvailableSince);
}

[Test]
public void CreateCtor_EnsureValidName ()
{
Expand All @@ -28,42 +57,84 @@ public void CreateCtor_EnsureValidName ()
Assert.AreEqual ("_3", klass.Ctors[0].Name);
}

[Test]
public void CreateCtor_CorrectApiSince ()
{
var xml = XDocument.Parse ("<package name='com.example.test' jni-name='com/example/test'><class name='test'><constructor name='ctor' api-since='7' /></class></package>");
var klass = XmlApiImporter.CreateClass (xml.Root, xml.Root.Element ("class"), opt);

Assert.AreEqual (7, klass.Ctors [0].ApiAvailableSince);
}

[Test]
public void CreateCtor_CorrectApiSinceFromClass ()
{
var xml = XDocument.Parse ("<package name='com.example.test' jni-name='com/example/test'><class name='test' api-since='7'><constructor name='ctor' /></class></package>");
var klass = XmlApiImporter.CreateClass (xml.Root, xml.Root.Element ("class"), opt);

Assert.AreEqual (7, klass.Ctors [0].ApiAvailableSince);
}

[Test]
public void CreateField_StudlyCaseName ()
{
var klass = new TestClass ("object", "MyNamespace.MyType");
var xml = XDocument.Parse ("<field name=\"_DES_EDE_CBC\" />");
var field = XmlApiImporter.CreateField (xml.Root);
var field = XmlApiImporter.CreateField (klass, xml.Root);

Assert.AreEqual ("DesEdeCbc", field.Name);
}

[Test]
public void CreateField_EnsureValidName ()
{
var klass = new TestClass ("object", "MyNamespace.MyType");
var xml = XDocument.Parse ("<field name=\"_3DES_EDE_CBC\" />");
var field = XmlApiImporter.CreateField (xml.Root);
var field = XmlApiImporter.CreateField (klass, xml.Root);

Assert.AreEqual ("_3desEdeCbc", field.Name);
}

[Test]
public void CreateField_HandleDollarSign ()
{
var klass = new TestClass ("object", "MyNamespace.MyType");
var xml = XDocument.Parse ("<field name=\"A$3\" />");
var field = XmlApiImporter.CreateField (xml.Root);
var field = XmlApiImporter.CreateField (klass, xml.Root);

Assert.AreEqual ("A_3", field.Name);
}

[Test]
public void CreateField_HandleDollarSignNumber ()
{
var klass = new TestClass ("object", "MyNamespace.MyType");
var xml = XDocument.Parse ("<field name=\"$3\" />");
var field = XmlApiImporter.CreateField (xml.Root);
var field = XmlApiImporter.CreateField (klass, xml.Root);

Assert.AreEqual ("_3", field.Name);
}

[Test]
public void CreateField_CorrectApiVersion ()
{
var klass = new TestClass ("object", "MyNamespace.MyType");
var xml = XDocument.Parse ("<field name='$3' api-since='7' />");
var field = XmlApiImporter.CreateField (klass, xml.Root);

Assert.AreEqual (7, field.ApiAvailableSince);
}

[Test]
public void CreateField_CorrectApiVersionFromClass ()
{
var klass = new TestClass ("object", "MyNamespace.MyType") { ApiAvailableSince = 7 };
var xml = XDocument.Parse ("<field name='$3' />");
var field = XmlApiImporter.CreateField (klass, xml.Root);

Assert.AreEqual (7, field.ApiAvailableSince);
}

[Test]
public void CreateInterface_EnsureValidName ()
{
Expand All @@ -73,6 +144,35 @@ public void CreateInterface_EnsureValidName ()
Assert.AreEqual ("I_3", iface.Name);
}

[Test]
public void CreateInterface_CorrectApiSince ()
{
var xml = XDocument.Parse ("<package name='com.example.test' jni-name='com/example/test'><interface name='myclass' api-since='7' /></package>");
var iface = XmlApiImporter.CreateClass (xml.Root, xml.Root.Element ("interface"), opt);

Assert.AreEqual (7, iface.ApiAvailableSince);
}

[Test]
public void CreateInterface_CorrectApiSinceFromPackage ()
{
// Make sure we inherit it from <package>.
var xml = XDocument.Parse ("<package name='com.example.test' jni-name='com/example/test' api-since='7'><interface name='myclass' /></package>");
var iface = XmlApiImporter.CreateClass (xml.Root, xml.Root.Element ("interface"), opt);

Assert.AreEqual (7, iface.ApiAvailableSince);
}

[Test]
public void CreateInterface_CorrectApiSinceOverridePackage ()
{
// Make sure we inherit it from <package>.
var xml = XDocument.Parse ("<package name='com.example.test' jni-name='com/example/test' api-since='7'><interface name='myclass' api-since='9' /></package>");
var iface = XmlApiImporter.CreateInterface (xml.Root, xml.Root.Element ("interface"), opt);

Assert.AreEqual (9, iface.ApiAvailableSince);
}

[Test]
public void CreateMethod_EnsureValidName ()
{
Expand All @@ -91,6 +191,24 @@ public void CreateMethod_EnsureValidNameHyphen ()
Assert.AreEqual ("_3", klass.Methods [0].Name);
}

[Test]
public void CreateMethod_CorrectApiSince ()
{
var xml = XDocument.Parse ("<package name='com.example.test' jni-name='com/example/test'><class name='test'><method name='-3' api-since='7' /></class></package>");
var klass = XmlApiImporter.CreateClass (xml.Root, xml.Root.Element ("class"), opt);

Assert.AreEqual (7, klass.Methods [0].ApiAvailableSince);
}

[Test]
public void CreateMethod_CorrectApiSinceFromClass ()
{
var xml = XDocument.Parse ("<package name='com.example.test' jni-name='com/example/test'><class name='test' api-since='7'><method name='-3' /></class></package>");
var klass = XmlApiImporter.CreateClass (xml.Root, xml.Root.Element ("class"), opt);

Assert.AreEqual (7, klass.Methods [0].ApiAvailableSince);
}

[Test]
public void CreateParameter_EnsureValidName ()
{
Expand Down
2 changes: 1 addition & 1 deletion tests/generator-Tests/Unit-Tests/XmlTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ public void Field ()
{
var element = package.Element ("class");
var @class = XmlApiImporter.CreateClass (package, element, options);
var field = XmlApiImporter.CreateField (element.Element ("field"));
var field = XmlApiImporter.CreateField (@class, element.Element ("field"));
Assert.IsTrue (field.Validate (options, new GenericParameterDefinitionList (), new CodeGeneratorContext ()), "field.Validate failed!");

Assert.AreEqual ("Value", field.Name);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ public static ClassGen CreateClass (XElement pkg, XElement elem, CodeGenerationO
!options.SupportNestedInterfaceTypes
};

FillApiSince (klass, pkg, elem);

foreach (var child in elem.Elements ()) {
switch (child.Name.LocalName) {
case "implements":
Expand All @@ -39,7 +41,7 @@ public static ClassGen CreateClass (XElement pkg, XElement elem, CodeGenerationO
klass.Ctors.Add (CreateCtor (klass, child));
break;
case "field":
klass.AddField (CreateField (child));
klass.AddField (CreateField (klass, child));
break;
case "typeParameters":
break; // handled at GenBaseSupport
Expand All @@ -55,6 +57,7 @@ public static ClassGen CreateClass (XElement pkg, XElement elem, CodeGenerationO
public static Ctor CreateCtor (GenBase declaringType, XElement elem)
{
var ctor = new Ctor (declaringType) {
ApiAvailableSince = declaringType.ApiAvailableSince,
CustomAttributes = elem.XGetAttribute ("customAttributes"),
Deprecated = elem.Deprecated (),
GenericArguments = elem.GenericArguments (),
Expand Down Expand Up @@ -90,12 +93,15 @@ public static Ctor CreateCtor (GenBase declaringType, XElement elem)

ctor.Name = EnsureValidIdentifer (ctor.Name);

FillApiSince (ctor, elem);

return ctor;
}

public static Field CreateField (XElement elem)
public static Field CreateField (GenBase declaringType, XElement elem)
{
var field = new Field {
ApiAvailableSince = declaringType.ApiAvailableSince,
DeprecatedComment = elem.XGetAttribute ("deprecated"),
IsAcw = true,
IsDeprecated = elem.XGetAttribute ("deprecated") != "not deprecated",
Expand Down Expand Up @@ -124,6 +130,8 @@ public static Field CreateField (XElement elem)
field.Name = EnsureValidIdentifer (field.Name);
}

FillApiSince (field, elem);

return field;
}

Expand Down Expand Up @@ -205,6 +213,8 @@ public static InterfaceGen CreateInterface (XElement pkg, XElement elem, CodeGen
!options.SupportNestedInterfaceTypes
};

FillApiSince (iface, pkg, elem);

foreach (var child in elem.Elements ()) {
switch (child.Name.LocalName) {
case "implements":
Expand All @@ -216,7 +226,7 @@ public static InterfaceGen CreateInterface (XElement pkg, XElement elem, CodeGen
iface.AddMethod (CreateMethod (iface, child));
break;
case "field":
iface.AddField (CreateField (child));
iface.AddField (CreateField (iface, child));
break;
case "typeParameters":
break; // handled at GenBaseSupport
Expand All @@ -232,6 +242,7 @@ public static InterfaceGen CreateInterface (XElement pkg, XElement elem, CodeGen
public static Method CreateMethod (GenBase declaringType, XElement elem)
{
var method = new Method (declaringType) {
ApiAvailableSince = declaringType.ApiAvailableSince,
ArgsType = elem.Attribute ("argsType")?.Value,
CustomAttributes = elem.XGetAttribute ("customAttributes"),
Deprecated = elem.Deprecated (),
Expand Down Expand Up @@ -279,6 +290,8 @@ public static Method CreateMethod (GenBase declaringType, XElement elem)

method.FillReturnType ();

FillApiSince (method, elem);

return method;
}

Expand Down Expand Up @@ -350,6 +363,20 @@ static XElement GetPreviousClass (XNode n, string nameValue)
return e;
}

// The array here allows members to inherit defaults from their parent, but
// override them if they were added later.
// For example:
// - <package api-since="21">
// - <class api-since="24">
// - <method api-since="28">
// Elements need to be passed in the above order. (package, class, member)
static void FillApiSince (ApiVersionsSupport.IApiAvailability model, params XElement[] elems)
{
foreach (var elem in elems)
if (int.TryParse (elem.XGetAttribute ("api-since"), out var result))
model.ApiAvailableSince = result;
}

static bool IsObfuscatedName (int threshold, string name)
{
if (name.StartsWith ("R.", StringComparison.Ordinal))
Expand Down