[tests] Simplify the MT4164 test a bit. (#2151)

* [tests] Add support to mtouch tests for comparing file name & line number of error/warning messages.

* [tests] Simplify the MT4164 test a bit.
This commit is contained in:
Rolf Bjarne Kvinge 2017-06-01 01:10:36 +02:00 коммит произвёл GitHub
Родитель c199c9f2c2
Коммит 25e6a93976
2 изменённых файлов: 81 добавлений и 91 удалений

Просмотреть файл

@ -20,8 +20,17 @@ namespace Xamarin.Tests
public int Number;
public string PrefixedNumber { get { return Prefix + Number.ToString (); } }
public string Message;
// public string Filename;
// public int LineNumber;
public string FileName;
public int LineNumber;
public override string ToString ()
{
if (string.IsNullOrEmpty (FileName)) {
return String.Format ("{0} {3}{1:0000}: {2}", IsError ? "error" : "warning", Number, Message, Prefix);
} else {
return String.Format ("{3}({4}): {0} {5}{1:0000}: {2}", IsError ? "error" : "warning", Number, Message, FileName, LineNumber, Prefix);
}
}
}
class Tool
@ -75,7 +84,17 @@ namespace Xamarin.Tests
foreach (var l in output.ToString ().Split ('\n')) {
var line = l;
var msg = new ToolMessage ();
if (line.StartsWith ("error ", StringComparison.Ordinal)) {
var origin = string.Empty;
if (line.Contains (": error ")) {
msg.IsError = true;
var idx = line.IndexOf (": error ", StringComparison.Ordinal);
origin = line.Substring (0, idx);
line = line.Substring (idx + ": error ".Length);
} else if (line.Contains (": warning ")) {
var idx = line.IndexOf (": warning ", StringComparison.Ordinal);
origin = line.Substring (0, idx);
line = line.Substring (idx + ": warning ".Length);
} else if (line.StartsWith ("error ", StringComparison.Ordinal)) {
msg.IsError = true;
line = line.Substring (6);
} else if (line.StartsWith ("warning ", StringComparison.Ordinal)) {
@ -92,6 +111,20 @@ namespace Xamarin.Tests
continue; // something else
msg.Message = line.Substring (8);
if (!string.IsNullOrEmpty (origin)) {
var idx = origin.IndexOf ('(');
if (idx > 0) {
var closing = origin.IndexOf (')');
var number = 0;
if (!int.TryParse (origin.Substring (idx + 1, closing - idx - 1), out number))
continue;
msg.LineNumber = number;
msg.FileName = origin.Substring (0, idx);
} else {
msg.FileName = origin;
}
}
messages.Add (msg);
}
}
@ -131,21 +164,46 @@ namespace Xamarin.Tests
Assert.Fail (string.Format ("The error '{0}{1:0000}: {2}' was not found in the output:\n{3}", prefix, number, messagePattern, string.Join ("\n", details.ToArray ())));
}
public void AssertError (int number, string message)
public void AssertError (int number, string message, string filename = null, int? linenumber = null)
{
AssertError ("MT", number, message);
AssertError ("MT", number, message, filename, linenumber);
}
public void AssertError (string prefix, int number, string message)
public void AssertError (string prefix, int number, string message, string filename = null, int? linenumber = null)
{
if (!messages.Any ((msg) => msg.Prefix == prefix && msg.Number == number))
Assert.Fail (string.Format ("The error '{0}{1:0000}' was not found in the output.", prefix, number));
if (messages.Any ((msg) => msg.Message == message))
return;
var matches = messages.Where ((msg) => msg.Message == message);
if (!matches.Any ()) {
var details = messages.
Where ((msg) => msg.Prefix == prefix && msg.Number == number && msg.Message != message).
Select ((msg) => string.Format ("\tMessage #{2} did not match:\n\t\tactual: '{0}'\n\t\texpected: '{1}'", msg.Message, message, messages.IndexOf (msg) + 1));
Assert.Fail (string.Format ("The error '{0}{1:0000}: {2}' was not found in the output:\n{3}", prefix, number, message, string.Join ("\n", details.ToArray ())));
}
var details = messages.Where ((msg) => msg.Prefix == prefix && msg.Number == number && msg.Message != message).Select ((msg) => string.Format ("\tMessage #{2} did not match:\n\t\tactual: '{0}'\n\t\texpected: '{1}'", msg.Message, message, messages.IndexOf (msg) + 1));
Assert.Fail (string.Format ("The error '{0}{1:0000}: {2}' was not found in the output:\n{3}", prefix, number, message, string.Join ("\n", details.ToArray ())));
if (filename != null) {
var hasDirectory = filename.IndexOf (Path.DirectorySeparatorChar) > -1;
if (!matches.Any ((v) => {
if (hasDirectory) {
// Check the entire path
return filename == v.FileName;
} else {
// Don't compare the directory unless one was specified.
return filename == Path.GetFileName (v.FileName);
}
})) {
var details = matches.Select ((msg) => string.Format ("\tMessage #{2} did not contain expected filename:\n\t\tactual: '{0}'\n\t\texpected: '{1}'", hasDirectory ? msg.FileName : Path.GetFileName (msg.FileName), filename, messages.IndexOf (msg) + 1));
Assert.Fail (string.Format ($"The filename '{filename}' was not found in the output for the error {prefix}{number:X4}: {message}:\n{string.Join ("\n", details.ToArray ())}"));
}
}
if (linenumber != null) {
if (!matches.Any ((v) => linenumber.Value == v.LineNumber)) {
var details = matches.Select ((msg) => string.Format ("\tMessage #{2} did not contain expected line number:\n\t\tactual: '{0}'\n\t\texpected: '{1}'", msg.LineNumber, linenumber, messages.IndexOf (msg) + 1));
Assert.Fail (string.Format ($"The linenumber '{linenumber.Value}' was not found in the output for the error {prefix}{number:X4}: {message}:\n{string.Join ("\n", details.ToArray ())}"));
}
}
}
public void AssertWarningPattern (int number, string messagePattern)

Просмотреть файл

@ -633,87 +633,19 @@ public struct FooF { public NSObject Obj; }
[Test]
public void MT4164 ()
{
var code = @"
class FutureType : NSObject
{
[Export (""auto"")] string Auto { get; set; }
[Export (""break"")] string Break { get; set; }
[Export (""case"")] string Case { get; set; }
[Export (""char"")] string Char { get; set; }
[Export (""const"")] string Const { get; set; }
[Export (""continue"")] string Continue { get; set; }
[Export (""default"")] string Default { get; set; }
[Export (""do"")] string Do { get; set; }
[Export (""double"")] string Double { get; set; }
[Export (""else"")] string Else { get; set; }
[Export (""enum"")] string Enum { get; set; }
[Export (""export"")] string Export { get; set; }
[Export (""extern"")] string Extern { get; set; }
[Export (""float"")] string Float { get; set; }
[Export (""for"")] string For { get; set; }
[Export (""goto"")] string Goto { get; set; }
[Export (""if"")] string If { get; set; }
[Export (""inline"")] string Inline { get; set; }
[Export (""int"")] string Int { get; set; }
[Export (""long"")] string Long { get; set; }
[Export (""register"")] string Register { get; set; }
[Export (""return"")] string Return { get; set; }
[Export (""short"")] string Short { get; set; }
[Export (""signed"")] string Signed { get; set; }
[Export (""sizeof"")] string Sizeof { get; set; }
[Export (""static"")] string Static { get; set; }
[Export (""struct"")] string Struct { get; set; }
[Export (""switch"")] string Switch { get; set; }
[Export (""template"")] string Template { get; set; }
[Export (""typedef"")] string Typedef { get; set; }
[Export (""union"")] string Union { get; set; }
[Export (""unsigned"")] string Unsigned { get; set; }
[Export (""void"")] string Void { get; set; }
[Export (""volatile"")] string Volatile { get; set; }
[Export (""while"")] string While { get; set; }
[Export (""_Bool"")] string Bool { get; set; }
[Export (""_Complex"")] string Complex { get; set; }
}
";
Verify (R.Static, Profile.iOS, code, false, Target.Sim,
".*/Test.cs(.*): error MT4164: Cannot export the property 'Auto' because its selector 'auto' is an Objective-C keyword. Please use a different name.",
".*/Test.cs(.*): error MT4164: Cannot export the property 'Break' because its selector 'break' is an Objective-C keyword. Please use a different name.",
".*/Test.cs(.*): error MT4164: Cannot export the property 'Case' because its selector 'case' is an Objective-C keyword. Please use a different name.",
".*/Test.cs(.*): error MT4164: Cannot export the property 'Char' because its selector 'char' is an Objective-C keyword. Please use a different name.",
".*/Test.cs(.*): error MT4164: Cannot export the property 'Const' because its selector 'const' is an Objective-C keyword. Please use a different name.",
".*/Test.cs(.*): error MT4164: Cannot export the property 'Continue' because its selector 'continue' is an Objective-C keyword. Please use a different name.",
".*/Test.cs(.*): error MT4164: Cannot export the property 'Default' because its selector 'default' is an Objective-C keyword. Please use a different name.",
".*/Test.cs(.*): error MT4164: Cannot export the property 'Do' because its selector 'do' is an Objective-C keyword. Please use a different name.",
".*/Test.cs(.*): error MT4164: Cannot export the property 'Double' because its selector 'double' is an Objective-C keyword. Please use a different name.",
".*/Test.cs(.*): error MT4164: Cannot export the property 'Else' because its selector 'else' is an Objective-C keyword. Please use a different name.",
".*/Test.cs(.*): error MT4164: Cannot export the property 'Enum' because its selector 'enum' is an Objective-C keyword. Please use a different name.",
".*/Test.cs(.*): error MT4164: Cannot export the property 'Export' because its selector 'export' is an Objective-C keyword. Please use a different name.",
".*/Test.cs(.*): error MT4164: Cannot export the property 'Extern' because its selector 'extern' is an Objective-C keyword. Please use a different name.",
".*/Test.cs(.*): error MT4164: Cannot export the property 'Float' because its selector 'float' is an Objective-C keyword. Please use a different name.",
".*/Test.cs(.*): error MT4164: Cannot export the property 'For' because its selector 'for' is an Objective-C keyword. Please use a different name.",
".*/Test.cs(.*): error MT4164: Cannot export the property 'Goto' because its selector 'goto' is an Objective-C keyword. Please use a different name.",
".*/Test.cs(.*): error MT4164: Cannot export the property 'If' because its selector 'if' is an Objective-C keyword. Please use a different name.",
".*/Test.cs(.*): error MT4164: Cannot export the property 'Inline' because its selector 'inline' is an Objective-C keyword. Please use a different name.",
".*/Test.cs(.*): error MT4164: Cannot export the property 'Int' because its selector 'int' is an Objective-C keyword. Please use a different name.",
".*/Test.cs(.*): error MT4164: Cannot export the property 'Long' because its selector 'long' is an Objective-C keyword. Please use a different name.",
".*/Test.cs(.*): error MT4164: Cannot export the property 'Register' because its selector 'register' is an Objective-C keyword. Please use a different name.",
".*/Test.cs(.*): error MT4164: Cannot export the property 'Return' because its selector 'return' is an Objective-C keyword. Please use a different name.",
".*/Test.cs(.*): error MT4164: Cannot export the property 'Short' because its selector 'short' is an Objective-C keyword. Please use a different name.",
".*/Test.cs(.*): error MT4164: Cannot export the property 'Signed' because its selector 'signed' is an Objective-C keyword. Please use a different name.",
".*/Test.cs(.*): error MT4164: Cannot export the property 'Sizeof' because its selector 'sizeof' is an Objective-C keyword. Please use a different name.",
".*/Test.cs(.*): error MT4164: Cannot export the property 'Static' because its selector 'static' is an Objective-C keyword. Please use a different name.",
".*/Test.cs(.*): error MT4164: Cannot export the property 'Struct' because its selector 'struct' is an Objective-C keyword. Please use a different name.",
".*/Test.cs(.*): error MT4164: Cannot export the property 'Switch' because its selector 'switch' is an Objective-C keyword. Please use a different name.",
".*/Test.cs(.*): error MT4164: Cannot export the property 'Template' because its selector 'template' is an Objective-C keyword. Please use a different name.",
".*/Test.cs(.*): error MT4164: Cannot export the property 'Typedef' because its selector 'typedef' is an Objective-C keyword. Please use a different name.",
".*/Test.cs(.*): error MT4164: Cannot export the property 'Union' because its selector 'union' is an Objective-C keyword. Please use a different name.",
".*/Test.cs(.*): error MT4164: Cannot export the property 'Unsigned' because its selector 'unsigned' is an Objective-C keyword. Please use a different name.",
".*/Test.cs(.*): error MT4164: Cannot export the property 'Void' because its selector 'void' is an Objective-C keyword. Please use a different name.",
".*/Test.cs(.*): error MT4164: Cannot export the property 'Volatile' because its selector 'volatile' is an Objective-C keyword. Please use a different name.",
".*/Test.cs(.*): error MT4164: Cannot export the property 'While' because its selector 'while' is an Objective-C keyword. Please use a different name.",
".*/Test.cs(.*): error MT4164: Cannot export the property 'Bool' because its selector '_Bool' is an Objective-C keyword. Please use a different name.",
".*/Test.cs(.*): error MT4164: Cannot export the property 'Complex' because its selector '_Complex' is an Objective-C keyword. Please use a different name.");
using (var mtouch = new MTouchTool ()) {
var sb = new StringBuilder ();
sb.AppendLine ("class FutureType : Foundation.NSObject {");
foreach (var kw in objective_c_keywords)
sb.AppendLine ($"[Foundation.Export (\"{kw}\")] string X{kw} {{ get; set; }}");
sb.AppendLine ("}");
mtouch.Linker = MTouchLinker.DontLink;
mtouch.Registrar = MTouchRegistrar.Static;
mtouch.CreateTemporaryApp (extraCode: sb.ToString (), extraArg: "-debug");
mtouch.AssertExecuteFailure (MTouchAction.BuildSim, "build");
foreach (var kw in objective_c_keywords)
mtouch.AssertError (4164, $"Cannot export the property 'X{kw}' because its selector '{kw}' is an Objective-C keyword. Please use a different name.", "testApp.cs");
}
}
[Test]