From 76b1b21805dc705f2ce421c796a022a332c5de88 Mon Sep 17 00:00:00 2001 From: NikolayPianikov Date: Fri, 8 Jul 2022 23:48:02 +0300 Subject: [PATCH 1/3] Use pure DI --- .gitignore | 1 + src/extension/Composer.cs | 47 ++++++ src/extension/Event.cs | 25 ++- src/extension/EventConverter2.cs | 2 +- src/extension/EventConverter3.cs | 2 +- src/extension/EventId.cs | 27 ++- src/extension/EventListener.cs | 157 ++++++++++++++++++ src/extension/Hierarchy.cs | 27 ++- src/extension/IEventConverter.cs | 25 ++- src/extension/IHierarchy.cs | 27 ++- src/extension/IServiceMessageFactory.cs | 27 ++- src/extension/IServiceMessageWriter.cs | 25 ++- src/extension/ISuiteNameReplacer.cs | 27 ++- src/extension/ITeamCityInfo.cs | 25 ++- src/extension/ServiceMessageFactory.cs | 27 ++- src/extension/ServiceMessageWriter.cs | 25 ++- src/extension/Statistics.cs | 27 ++- src/extension/SuiteNameReplacer.cs | 25 ++- src/extension/TeamCityEventListener.cs | 112 +------------ src/extension/TeamCityInfo.cs | 25 ++- src/extension/TeamCityVersion.cs | 25 ++- src/extension/teamcity-event-listener.csproj | 6 + .../TeamCityEventListener2IntegrationTests.cs | 4 +- .../TeamCityEventListener3IntegrationTests.cs | 4 +- .../TeamCityEventListenerIntegrationTests.cs | 6 +- src/tests/TestUtil.cs | 22 +++ 26 files changed, 613 insertions(+), 139 deletions(-) create mode 100644 src/extension/Composer.cs create mode 100644 src/extension/EventListener.cs diff --git a/.gitignore b/.gitignore index 5d5b5d8..6e2635e 100644 --- a/.gitignore +++ b/.gitignore @@ -179,3 +179,4 @@ MockAssemblyResult.xml PortabilityAnalysis*.html tools/nuget.exe tools/ +.idea/ diff --git a/src/extension/Composer.cs b/src/extension/Composer.cs new file mode 100644 index 0000000..ebe4d2e --- /dev/null +++ b/src/extension/Composer.cs @@ -0,0 +1,47 @@ +// *********************************************************************** +// Copyright (c) 2015 Charlie Poole +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// *********************************************************************** + +namespace NUnit.Engine.Listeners +{ + using System; + using System.IO; + using Pure.DI; + + public static partial class Composer + { + private static void Setup() + { + DI.Setup() + .Bind().To(ctx => Console.Out) + .Bind().To() + .Bind().To() + .Bind().To() + .Bind().To() + .Bind().To() + .Bind().To() + .Bind(2).To() + .Bind(3).To() + .Bind().To(); + } + } +} \ No newline at end of file diff --git a/src/extension/Event.cs b/src/extension/Event.cs index a4b8cac..c0b49f9 100644 --- a/src/extension/Event.cs +++ b/src/extension/Event.cs @@ -1,4 +1,27 @@ -namespace NUnit.Engine.Listeners +// *********************************************************************** +// Copyright (c) 2015 Charlie Poole +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// *********************************************************************** + +namespace NUnit.Engine.Listeners { using System.Xml; diff --git a/src/extension/EventConverter2.cs b/src/extension/EventConverter2.cs index 129f2af..b7a45ea 100644 --- a/src/extension/EventConverter2.cs +++ b/src/extension/EventConverter2.cs @@ -27,7 +27,7 @@ namespace NUnit.Engine.Listeners using System.Xml; using System.Collections.Generic; - internal class EventConverter2: IEventConverter + public class EventConverter2: IEventConverter { private readonly IServiceMessageFactory _serviceMessageFactory; private readonly IHierarchy _hierarchy; diff --git a/src/extension/EventConverter3.cs b/src/extension/EventConverter3.cs index aeaeba1..bed1fbd 100644 --- a/src/extension/EventConverter3.cs +++ b/src/extension/EventConverter3.cs @@ -27,7 +27,7 @@ namespace NUnit.Engine.Listeners using System.Xml; using System.Collections.Generic; - internal class EventConverter3: IEventConverter + public class EventConverter3: IEventConverter { private readonly IServiceMessageFactory _serviceMessageFactory; private readonly IHierarchy _hierarchy; diff --git a/src/extension/EventId.cs b/src/extension/EventId.cs index 647b6a9..5f701d3 100644 --- a/src/extension/EventId.cs +++ b/src/extension/EventId.cs @@ -1,6 +1,29 @@ -namespace NUnit.Engine.Listeners +// *********************************************************************** +// Copyright (c) 2015 Charlie Poole +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// *********************************************************************** + +namespace NUnit.Engine.Listeners { - internal struct EventId + public struct EventId { public readonly string FlowId; public readonly string FullName; diff --git a/src/extension/EventListener.cs b/src/extension/EventListener.cs new file mode 100644 index 0000000..a5da0d8 --- /dev/null +++ b/src/extension/EventListener.cs @@ -0,0 +1,157 @@ +// *********************************************************************** +// Copyright (c) 2015 Charlie Poole +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// *********************************************************************** + +namespace NUnit.Engine.Listeners +{ + using System.Diagnostics.CodeAnalysis; + using System.Text; + using System; + using System.IO; + using System.Xml; + using Extensibility; + using Pure.DI; + + // Note: Setting minimum engine version in this case is + // purely documentary since engines prior to 3.4 do not + // check the EngineVersion property and will try to + // load this extension anyway. + [Extension(Enabled = false, EngineVersion = "3.4")] + [SuppressMessage("ReSharper", "UseNameofExpression")] + public class EventListener : ITestEventListener + { + private readonly IServiceMessageWriter _serviceMessageWriter; + private readonly IEventConverter _eventConverter2; + private readonly IEventConverter _eventConverter3; + private readonly Statistics _statistics; + private readonly ITeamCityInfo _teamCityInfo; + private readonly object _lockObject = new object(); + private readonly TextWriter _outWriter; + private string _rootFlowId = string.Empty; + + // ReSharper disable once UnusedMember.Global + public EventListener( + TextWriter outWriter, + ITeamCityInfo teamCityInfo, + Statistics statistics, + IServiceMessageWriter serviceMessageWriter, + [Tag(2)] IEventConverter eventConverter2, + [Tag(3)] IEventConverter eventConverter3) + { + if (outWriter == null) throw new ArgumentNullException("outWriter"); + if (teamCityInfo == null) throw new ArgumentNullException("teamCityInfo"); + if (statistics == null) throw new ArgumentNullException("statistics"); + _outWriter = outWriter; + _teamCityInfo = teamCityInfo; + _statistics = statistics; + _serviceMessageWriter = serviceMessageWriter; + _eventConverter2 = eventConverter2; + _eventConverter3 = eventConverter3; + RootFlowId = _teamCityInfo.RootFlowId; + } + + public string RootFlowId + { + set + { + _rootFlowId = value ?? string.Empty; + } + } + + public void OnTestEvent(string report) + { + if (_teamCityInfo.AllowDiagnostics) + { + _outWriter.WriteLine(); + _outWriter.WriteLine("PID_" + _teamCityInfo.ProcessId + " !!!!{ " + report + " }!!!!"); + } + + var doc = new XmlDocument(); + doc.LoadXml(report); + + var testEvent = doc.FirstChild; + RegisterMessage(testEvent); + } + + public void RegisterMessage(XmlNode xmlEvent) + { + if (xmlEvent == null) throw new ArgumentNullException("xmlEvent"); + var messageName = xmlEvent.Name; + if (string.IsNullOrEmpty(messageName)) + { + return; + } + + var fullName = xmlEvent.GetAttribute("fullname"); + if (string.IsNullOrEmpty(fullName)) + { + fullName = xmlEvent.GetAttribute("testname"); + if (string.IsNullOrEmpty(fullName)) + { + return; + } + } + + var name = xmlEvent.GetAttribute("name"); + if (string.IsNullOrEmpty(name)) + { + name = fullName; + } + + var id = xmlEvent.GetAttribute("id") ?? string.Empty; + var parentId = xmlEvent.GetAttribute("parentId"); + var testId = xmlEvent.GetAttribute("testid"); + + var isNUnit3 = parentId != null; + var eventConverter = isNUnit3 ? _eventConverter3 : _eventConverter2; + var testEvent = new Event(_rootFlowId, messageName.ToLowerInvariant(), fullName, name, GetId(_rootFlowId, id), GetId(_rootFlowId, parentId), GetId(_rootFlowId, testId), xmlEvent); + lock (_lockObject) + { + var sb = new StringBuilder(); + using (var writer = new StringWriter(sb)) + { + foreach (var messages in eventConverter.Convert(testEvent)) + { + _serviceMessageWriter.Write(writer, messages); + } + } + + _outWriter.Write(sb.ToString()); + } + + if (_teamCityInfo.AllowDiagnostics) + { + _outWriter.WriteLine("@@ NUnit3: " + isNUnit3 + ", " + _statistics + ", " + testEvent); + } + } + + private static string GetId(string rootFlowId, string flowId) + { + if (string.IsNullOrEmpty(flowId) || string.IsNullOrEmpty(rootFlowId)) + { + return flowId; + } + + return rootFlowId + "_" + flowId; + } + } +} diff --git a/src/extension/Hierarchy.cs b/src/extension/Hierarchy.cs index 891c8be..6e9516d 100644 --- a/src/extension/Hierarchy.cs +++ b/src/extension/Hierarchy.cs @@ -1,9 +1,32 @@ -namespace NUnit.Engine.Listeners +// *********************************************************************** +// Copyright (c) 2015 Charlie Poole +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// *********************************************************************** + +namespace NUnit.Engine.Listeners { using System; using System.Collections.Generic; - internal class Hierarchy : IHierarchy + public class Hierarchy : IHierarchy { private readonly Dictionary _links = new Dictionary(); diff --git a/src/extension/IEventConverter.cs b/src/extension/IEventConverter.cs index eaeecba..b01042e 100644 --- a/src/extension/IEventConverter.cs +++ b/src/extension/IEventConverter.cs @@ -1,4 +1,27 @@ -namespace NUnit.Engine.Listeners +// *********************************************************************** +// Copyright (c) 2015 Charlie Poole +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// *********************************************************************** + +namespace NUnit.Engine.Listeners { using System.Collections.Generic; diff --git a/src/extension/IHierarchy.cs b/src/extension/IHierarchy.cs index 0860d1a..c86e2f3 100644 --- a/src/extension/IHierarchy.cs +++ b/src/extension/IHierarchy.cs @@ -1,6 +1,29 @@ -namespace NUnit.Engine.Listeners +// *********************************************************************** +// Copyright (c) 2015 Charlie Poole +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// *********************************************************************** + +namespace NUnit.Engine.Listeners { - internal interface IHierarchy + public interface IHierarchy { bool AddLink(string childId, string parentId); diff --git a/src/extension/IServiceMessageFactory.cs b/src/extension/IServiceMessageFactory.cs index 6124df7..433fa6a 100644 --- a/src/extension/IServiceMessageFactory.cs +++ b/src/extension/IServiceMessageFactory.cs @@ -1,11 +1,34 @@ -namespace NUnit.Engine.Listeners +// *********************************************************************** +// Copyright (c) 2015 Charlie Poole +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// *********************************************************************** + +namespace NUnit.Engine.Listeners { using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Xml; [SuppressMessage("ReSharper", "InconsistentNaming")] - internal interface IServiceMessageFactory + public interface IServiceMessageFactory { IEnumerable SuiteStarted(EventId eventId, Event testEvent); diff --git a/src/extension/IServiceMessageWriter.cs b/src/extension/IServiceMessageWriter.cs index 0592263..a46f8c9 100644 --- a/src/extension/IServiceMessageWriter.cs +++ b/src/extension/IServiceMessageWriter.cs @@ -1,4 +1,27 @@ -namespace NUnit.Engine.Listeners +// *********************************************************************** +// Copyright (c) 2015 Charlie Poole +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// *********************************************************************** + +namespace NUnit.Engine.Listeners { using System.Collections.Generic; using System.IO; diff --git a/src/extension/ISuiteNameReplacer.cs b/src/extension/ISuiteNameReplacer.cs index 6e8db9e..43ae9ec 100644 --- a/src/extension/ISuiteNameReplacer.cs +++ b/src/extension/ISuiteNameReplacer.cs @@ -1,6 +1,29 @@ -namespace NUnit.Engine.Listeners +// *********************************************************************** +// Copyright (c) 2015 Charlie Poole +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// *********************************************************************** + +namespace NUnit.Engine.Listeners { - internal interface ISuiteNameReplacer + public interface ISuiteNameReplacer { string Replace(string suiteName); } diff --git a/src/extension/ITeamCityInfo.cs b/src/extension/ITeamCityInfo.cs index 2798141..56f701e 100644 --- a/src/extension/ITeamCityInfo.cs +++ b/src/extension/ITeamCityInfo.cs @@ -1,4 +1,27 @@ -namespace NUnit.Engine.Listeners +// *********************************************************************** +// Copyright (c) 2015 Charlie Poole +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// *********************************************************************** + +namespace NUnit.Engine.Listeners { public interface ITeamCityInfo { diff --git a/src/extension/ServiceMessageFactory.cs b/src/extension/ServiceMessageFactory.cs index 8e3bc56..5653edd 100644 --- a/src/extension/ServiceMessageFactory.cs +++ b/src/extension/ServiceMessageFactory.cs @@ -1,4 +1,27 @@ -namespace NUnit.Engine.Listeners +// *********************************************************************** +// Copyright (c) 2015 Charlie Poole +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// *********************************************************************** + +namespace NUnit.Engine.Listeners { using System; using System.Collections.Generic; @@ -9,7 +32,7 @@ using System.Xml; [SuppressMessage("ReSharper", "InconsistentNaming")] - internal class ServiceMessageFactory : IServiceMessageFactory + public class ServiceMessageFactory : IServiceMessageFactory { private readonly ITeamCityInfo _teamCityInfo; private readonly ISuiteNameReplacer _suiteNameReplacer; diff --git a/src/extension/ServiceMessageWriter.cs b/src/extension/ServiceMessageWriter.cs index 0aeb2ac..64e4f1b 100644 --- a/src/extension/ServiceMessageWriter.cs +++ b/src/extension/ServiceMessageWriter.cs @@ -1,4 +1,27 @@ -namespace NUnit.Engine.Listeners +// *********************************************************************** +// Copyright (c) 2015 Charlie Poole +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// *********************************************************************** + +namespace NUnit.Engine.Listeners { using System; using System.Diagnostics.CodeAnalysis; diff --git a/src/extension/Statistics.cs b/src/extension/Statistics.cs index 910cff6..2a72983 100644 --- a/src/extension/Statistics.cs +++ b/src/extension/Statistics.cs @@ -1,6 +1,29 @@ -namespace NUnit.Engine.Listeners +// *********************************************************************** +// Copyright (c) 2015 Charlie Poole +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// *********************************************************************** + +namespace NUnit.Engine.Listeners { - internal class Statistics + public class Statistics { private long _suiteStart; private long _suiteFinish; diff --git a/src/extension/SuiteNameReplacer.cs b/src/extension/SuiteNameReplacer.cs index 929d249..8db522d 100644 --- a/src/extension/SuiteNameReplacer.cs +++ b/src/extension/SuiteNameReplacer.cs @@ -1,4 +1,27 @@ -namespace NUnit.Engine.Listeners +// *********************************************************************** +// Copyright (c) 2015 Charlie Poole +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// *********************************************************************** + +namespace NUnit.Engine.Listeners { using System.IO; diff --git a/src/extension/TeamCityEventListener.cs b/src/extension/TeamCityEventListener.cs index e7c6340..bd42cb7 100644 --- a/src/extension/TeamCityEventListener.cs +++ b/src/extension/TeamCityEventListener.cs @@ -24,10 +24,6 @@ namespace NUnit.Engine.Listeners { using System.Diagnostics.CodeAnalysis; - using System.Text; - using System; - using System.IO; - using System.Xml; using Extensibility; // Note: Setting minimum engine version in this case is @@ -38,117 +34,17 @@ namespace NUnit.Engine.Listeners [SuppressMessage("ReSharper", "UseNameofExpression")] public class TeamCityEventListener : ITestEventListener { - private readonly IServiceMessageWriter _serviceMessageWriter; - private readonly IEventConverter _eventConverter2; - private readonly IEventConverter _eventConverter3; - private readonly Statistics _statistics = new Statistics(); - private readonly ITeamCityInfo _teamCityInfo; - private readonly object _lockObject = new object(); - private readonly TextWriter _outWriter; - private string _rootFlowId = string.Empty; + private readonly ITestEventListener _listener; // ReSharper disable once UnusedMember.Global - public TeamCityEventListener() : this(Console.Out, new TeamCityInfo()) { } - - public TeamCityEventListener(TextWriter outWriter, ITeamCityInfo teamCityInfo) - { - if (outWriter == null) throw new ArgumentNullException("outWriter"); - if (teamCityInfo == null) throw new ArgumentNullException("teamCityInfo"); - - _outWriter = outWriter; - _teamCityInfo = teamCityInfo; - - _serviceMessageWriter = new ServiceMessageWriter(); - var serviceMessageFactory = new ServiceMessageFactory(_teamCityInfo, new SuiteNameReplacer(_teamCityInfo)); - var hierarchy = new Hierarchy(); - _eventConverter2 = new EventConverter2(serviceMessageFactory, hierarchy, _statistics, _teamCityInfo); - _eventConverter3 = new EventConverter3(serviceMessageFactory, hierarchy, _statistics, _teamCityInfo); - RootFlowId = _teamCityInfo.RootFlowId; - } - - public string RootFlowId + public TeamCityEventListener() { - set - { - _rootFlowId = value ?? string.Empty; - } + _listener = Composer.ResolveITestEventListener(); } public void OnTestEvent(string report) { - if (_teamCityInfo.AllowDiagnostics) - { - _outWriter.WriteLine(); - _outWriter.WriteLine("PID_" + _teamCityInfo.ProcessId + " !!!!{ " + report + " }!!!!"); - } - - var doc = new XmlDocument(); - doc.LoadXml(report); - - var testEvent = doc.FirstChild; - RegisterMessage(testEvent); - } - - public void RegisterMessage(XmlNode xmlEvent) - { - if (xmlEvent == null) throw new ArgumentNullException("xmlEvent"); - var messageName = xmlEvent.Name; - if (string.IsNullOrEmpty(messageName)) - { - return; - } - - var fullName = xmlEvent.GetAttribute("fullname"); - if (string.IsNullOrEmpty(fullName)) - { - fullName = xmlEvent.GetAttribute("testname"); - if (string.IsNullOrEmpty(fullName)) - { - return; - } - } - - var name = xmlEvent.GetAttribute("name"); - if (string.IsNullOrEmpty(name)) - { - name = fullName; - } - - var id = xmlEvent.GetAttribute("id") ?? string.Empty; - var parentId = xmlEvent.GetAttribute("parentId"); - var testId = xmlEvent.GetAttribute("testid"); - - var isNUnit3 = parentId != null; - var eventConverter = isNUnit3 ? _eventConverter3 : _eventConverter2; - var testEvent = new Event(_rootFlowId, messageName.ToLowerInvariant(), fullName, name, GetId(_rootFlowId, id), GetId(_rootFlowId, parentId), GetId(_rootFlowId, testId), xmlEvent); - lock (_lockObject) - { - var sb = new StringBuilder(); - using (var writer = new StringWriter(sb)) - { - foreach (var messages in eventConverter.Convert(testEvent)) - { - _serviceMessageWriter.Write(writer, messages); - } - } - - _outWriter.Write(sb.ToString()); - } - - if (_teamCityInfo.AllowDiagnostics) - { - _outWriter.WriteLine("@@ NUnit3: " + isNUnit3 + ", " + _statistics + ", " + testEvent); - } - } - - private static string GetId(string rootFlowId, string flowId) - { - if (string.IsNullOrEmpty(flowId) || string.IsNullOrEmpty(rootFlowId)) - { - return flowId; - } - - return rootFlowId + "_" + flowId; + _listener.OnTestEvent(report); } } } diff --git a/src/extension/TeamCityInfo.cs b/src/extension/TeamCityInfo.cs index 548bb72..c152bd4 100644 --- a/src/extension/TeamCityInfo.cs +++ b/src/extension/TeamCityInfo.cs @@ -1,4 +1,27 @@ -namespace NUnit.Engine.Listeners +// *********************************************************************** +// Copyright (c) 2015 Charlie Poole +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// *********************************************************************** + +namespace NUnit.Engine.Listeners { using System; using System.Collections.Generic; diff --git a/src/extension/TeamCityVersion.cs b/src/extension/TeamCityVersion.cs index 59fd2e2..b0226f8 100644 --- a/src/extension/TeamCityVersion.cs +++ b/src/extension/TeamCityVersion.cs @@ -1,4 +1,27 @@ -namespace NUnit.Engine.Listeners +// *********************************************************************** +// Copyright (c) 2015 Charlie Poole +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// *********************************************************************** + +namespace NUnit.Engine.Listeners { using System; using System.Text.RegularExpressions; diff --git a/src/extension/teamcity-event-listener.csproj b/src/extension/teamcity-event-listener.csproj index b229418..792d4b9 100644 --- a/src/extension/teamcity-event-listener.csproj +++ b/src/extension/teamcity-event-listener.csproj @@ -11,6 +11,8 @@ NUnit Engine extension that helps integration with TeamCity. net20;netstandard2.0 true + true + $(BaseIntermediateOutputPath)Generated @@ -44,6 +46,10 @@ + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + \ No newline at end of file diff --git a/src/tests/TeamCityEventListener2IntegrationTests.cs b/src/tests/TeamCityEventListener2IntegrationTests.cs index c9cbbf7..140ee31 100644 --- a/src/tests/TeamCityEventListener2IntegrationTests.cs +++ b/src/tests/TeamCityEventListener2IntegrationTests.cs @@ -322,9 +322,9 @@ public void ShouldSendMessagesWhenOneTimeSetUpFailed() _output.ToString()); } - private TeamCityEventListener CreateInstance() + private EventListener CreateInstance() { - return new TeamCityEventListener(_outputWriter, new TeamCityInfo()) { RootFlowId = string.Empty }; + return TestUtil.CreateListener(_outputWriter); } } } diff --git a/src/tests/TeamCityEventListener3IntegrationTests.cs b/src/tests/TeamCityEventListener3IntegrationTests.cs index 8f75448..7e8f873 100644 --- a/src/tests/TeamCityEventListener3IntegrationTests.cs +++ b/src/tests/TeamCityEventListener3IntegrationTests.cs @@ -415,9 +415,9 @@ public void ShouldSuppressParsingMessagesInside() _output.ToString()); } - private TeamCityEventListener CreateInstance(ITeamCityInfo teamCityInfo = null) + private EventListener CreateInstance(ITeamCityInfo info = null) { - return new TeamCityEventListener(_outputWriter, teamCityInfo != null ? teamCityInfo : new TeamCityInfo()) { RootFlowId = string.Empty }; + return TestUtil.CreateListener(_outputWriter, info); } private class MyTeamCityInfo : ITeamCityInfo diff --git a/src/tests/TeamCityEventListenerIntegrationTests.cs b/src/tests/TeamCityEventListenerIntegrationTests.cs index 547b26b..88d0de9 100644 --- a/src/tests/TeamCityEventListenerIntegrationTests.cs +++ b/src/tests/TeamCityEventListenerIntegrationTests.cs @@ -47,7 +47,7 @@ public void TearDown() } [Test] - [Ignore("")] + [Ignore("Manual run only")] public void ShouldSendMessages() { // Given @@ -67,9 +67,9 @@ public void ShouldSendMessages() var messages = _output.ToString(); } - private TeamCityEventListener CreateInstance() + private EventListener CreateInstance() { - return new TeamCityEventListener(_outputWriter, new TeamCityInfo()) { RootFlowId = string.Empty }; + return TestUtil.CreateListener(_outputWriter); } } } diff --git a/src/tests/TestUtil.cs b/src/tests/TestUtil.cs index 17f67ff..ec9e1c4 100644 --- a/src/tests/TestUtil.cs +++ b/src/tests/TestUtil.cs @@ -2,6 +2,7 @@ { using System; using System.Collections.Generic; + using System.IO; using System.Text; using System.Xml; @@ -11,6 +12,27 @@ public static class TestUtil private const string StartBlock = "!!!!{ "; private const string FinishBlock = " }!!!!"; + public static EventListener CreateListener(TextWriter outWriter, ITeamCityInfo info = null) + { + var statistics = new Statistics(); + if (info == null) + { + info = new TeamCityInfo(); + } + + var serviceMessageFactory = new ServiceMessageFactory(info, new SuiteNameReplacer(info)); + return new EventListener( + outWriter, + new TeamCityInfo(), + new Statistics(), + new ServiceMessageWriter(), + new EventConverter2(serviceMessageFactory, new Hierarchy(), statistics, info), + new EventConverter3(serviceMessageFactory, new Hierarchy(), statistics, info)) + { + RootFlowId = string.Empty + }; + } + public static XmlNode CreateStartRun(int count) { return CreateMessage(string.Format("", count)); From 553fdec71dfea33c6cb49eded17aadc091d40019 Mon Sep 17 00:00:00 2001 From: NikolayPianikov Date: Fri, 8 Jul 2022 23:56:47 +0300 Subject: [PATCH 2/3] Cleaning up the code --- src/extension/Composer.cs | 1 + src/extension/Event.cs | 1 + src/extension/EventConverter3.cs | 8 +- src/extension/Hierarchy.cs | 9 +- src/extension/SafeAttributeAccess.cs | 5 +- src/extension/ServiceMessageFactory.cs | 168 +++++++++--------- src/extension/TeamCityVersion.cs | 43 +++-- src/tests/ServiceMessageWriterTest.cs | 3 +- src/tests/SuiteNameReplacerTest.cs | 2 + .../TeamCityEventListener3IntegrationTests.cs | 2 + src/tests/TestUtil.cs | 44 +++-- 11 files changed, 148 insertions(+), 138 deletions(-) diff --git a/src/extension/Composer.cs b/src/extension/Composer.cs index ebe4d2e..c024816 100644 --- a/src/extension/Composer.cs +++ b/src/extension/Composer.cs @@ -21,6 +21,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // *********************************************************************** +// ReSharper disable UnusedMember.Local namespace NUnit.Engine.Listeners { using System; diff --git a/src/extension/Event.cs b/src/extension/Event.cs index c0b49f9..3176d6e 100644 --- a/src/extension/Event.cs +++ b/src/extension/Event.cs @@ -33,6 +33,7 @@ public struct Event public readonly string Name; public readonly string Id; public readonly string ParentId; + // ReSharper disable once InconsistentNaming public readonly string TestId; // ReSharper disable once InconsistentNaming public readonly XmlNode TestEvent; diff --git a/src/extension/EventConverter3.cs b/src/extension/EventConverter3.cs index bed1fbd..ac24bda 100644 --- a/src/extension/EventConverter3.cs +++ b/src/extension/EventConverter3.cs @@ -151,11 +151,13 @@ private IEnumerable ProcessNotStartedTests(string flowId, string var parentId = notStartedTest.Key; while (_hierarchy.TryFindParentId(parentId, out parentId)) { - if (id == parentId) + if (id != parentId) { - testToProcess.Add(notStartedTest.Key); - break; + continue; } + + testToProcess.Add(notStartedTest.Key); + break; } } diff --git a/src/extension/Hierarchy.cs b/src/extension/Hierarchy.cs index 6e9516d..9f2bb91 100644 --- a/src/extension/Hierarchy.cs +++ b/src/extension/Hierarchy.cs @@ -33,13 +33,14 @@ public class Hierarchy : IHierarchy public bool AddLink(string childId, string parentId) { string curParentId; - if (!_links.TryGetValue(childId, out curParentId) || curParentId != parentId) + if (_links.TryGetValue(childId, out curParentId) && curParentId == parentId) { - _links[childId] = parentId; - return true; + return false; } - return false; + _links[childId] = parentId; + return true; + } public void Clear() diff --git a/src/extension/SafeAttributeAccess.cs b/src/extension/SafeAttributeAccess.cs index 44e90b8..b8ca6ff 100644 --- a/src/extension/SafeAttributeAccess.cs +++ b/src/extension/SafeAttributeAccess.cs @@ -21,14 +21,13 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // *********************************************************************** -using System.Diagnostics.CodeAnalysis; using System.Xml; namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method)] - [SuppressMessage("ReSharper", "UnusedMember.Global")] - sealed class ExtensionAttribute : Attribute { } + // ReSharper disable once UnusedType.Global + public sealed class ExtensionAttribute : Attribute { } } namespace NUnit.Engine.Listeners diff --git a/src/extension/ServiceMessageFactory.cs b/src/extension/ServiceMessageFactory.cs index 5653edd..00e7219 100644 --- a/src/extension/ServiceMessageFactory.cs +++ b/src/extension/ServiceMessageFactory.cs @@ -368,102 +368,106 @@ private IEnumerable ReasonMessage(EventId eventId, XmlNode ev) private static IEnumerable Attachments(EventId eventId, XmlNode testEvent) { var attachments = testEvent.SelectNodes("attachments/attachment"); - if (attachments != null) + if (attachments == null) { - foreach (var attachment in attachments) + yield break; + } + + foreach (var attachment in attachments) + { + var attachmentElement = attachment as XmlNode; + if (attachmentElement == null) { - var attachmentElement = attachment as XmlNode; - if (attachmentElement == null) - { - continue; - } + continue; + } - var filePathNode = attachmentElement.SelectSingleNode("filePath"); - if (filePathNode != null) - { - var filePath = filePathNode.InnerText; - var descriptionNode = attachmentElement.SelectSingleNode("description"); - string description = null; - if (descriptionNode != null) - { - description = descriptionNode.InnerText; - } + var filePathNode = attachmentElement.SelectSingleNode("filePath"); + if (filePathNode == null) + { + continue; + } - var fileName = Path.GetFileName(filePath); - var fileExtension = Path.GetExtension(fileName).ToLowerInvariant(); + var filePath = filePathNode.InnerText; + var descriptionNode = attachmentElement.SelectSingleNode("description"); + string description = null; + if (descriptionNode != null) + { + description = descriptionNode.InnerText; + } - string artifactDir = null; - if (!string.IsNullOrEmpty(description)) - { - var match = AttachmentDescriptionRegex.Match(description); - if (match.Success) - { - description = match.Groups[1].Value.Trim(); - artifactDir = match.Groups[2].Value.Trim(); - } - } + var fileName = Path.GetFileName(filePath); + var fileExtension = Path.GetExtension(fileName).ToLowerInvariant(); - if (artifactDir == null) - { - var testDirNameChars = new char[eventId.FullName.Length]; - eventId.FullName.CopyTo(0, testDirNameChars, 0, eventId.FullName.Length); - for (var i = 0; i < testDirNameChars.Length; i++) - { - if (_invalidChars.Contains(testDirNameChars[i])) - { - testDirNameChars[i] = '_'; - } - } - - var testDirName = new string(testDirNameChars); - artifactDir = ".teamcity/NUnit/" + testDirName + "/" + Guid.NewGuid(); - } + string artifactDir = null; + if (!string.IsNullOrEmpty(description)) + { + var match = AttachmentDescriptionRegex.Match(description); + if (match.Success) + { + description = match.Groups[1].Value.Trim(); + artifactDir = match.Groups[2].Value.Trim(); + } + } - string artifactType; - switch (fileExtension) + if (artifactDir == null) + { + var testDirNameChars = new char[eventId.FullName.Length]; + eventId.FullName.CopyTo(0, testDirNameChars, 0, eventId.FullName.Length); + for (var i = 0; i < testDirNameChars.Length; i++) + { + if (_invalidChars.Contains(testDirNameChars[i])) { - case ".bmp": - case ".gif": - case ".ico": - case ".jng": - case ".jpeg": - case ".jpg": - case ".jfif": - case ".jp2": - case ".jps": - case ".tga": - case ".tiff": - case ".tif": - case ".svg": - case ".wmf": - case ".emf": - case ".png": - artifactType = "image"; - break; - - default: - artifactType = "artifact"; - break; + testDirNameChars[i] = '_'; } + } - yield return new ServiceMessage(ServiceMessage.Names.PublishArtifacts, filePath + " => " + artifactDir); + var testDirName = new string(testDirNameChars); + artifactDir = ".teamcity/NUnit/" + testDirName + "/" + Guid.NewGuid(); + } - var attrs = new List - { - new ServiceMessageAttr(ServiceMessageAttr.Names.FlowId, eventId.FlowId), - new ServiceMessageAttr(ServiceMessageAttr.Names.TestName, eventId.FullName), - new ServiceMessageAttr(ServiceMessageAttr.Names.Type, artifactType), - new ServiceMessageAttr(ServiceMessageAttr.Names.Value, artifactDir + "/" + fileName) - }; + string artifactType; + switch (fileExtension) + { + case ".bmp": + case ".gif": + case ".ico": + case ".jng": + case ".jpeg": + case ".jpg": + case ".jfif": + case ".jp2": + case ".jps": + case ".tga": + case ".tiff": + case ".tif": + case ".svg": + case ".wmf": + case ".emf": + case ".png": + artifactType = "image"; + break; + + default: + artifactType = "artifact"; + break; + } - if (!string.IsNullOrEmpty(description)) - { - attrs.Add(new ServiceMessageAttr(ServiceMessageAttr.Names.Name, description)); - } + yield return new ServiceMessage(ServiceMessage.Names.PublishArtifacts, filePath + " => " + artifactDir); - yield return new ServiceMessage(ServiceMessage.Names.TestMetadata, attrs); - } + var attrs = new List + { + new ServiceMessageAttr(ServiceMessageAttr.Names.FlowId, eventId.FlowId), + new ServiceMessageAttr(ServiceMessageAttr.Names.TestName, eventId.FullName), + new ServiceMessageAttr(ServiceMessageAttr.Names.Type, artifactType), + new ServiceMessageAttr(ServiceMessageAttr.Names.Value, artifactDir + "/" + fileName) + }; + + if (!string.IsNullOrEmpty(description)) + { + attrs.Add(new ServiceMessageAttr(ServiceMessageAttr.Names.Name, description)); } + + yield return new ServiceMessage(ServiceMessage.Names.TestMetadata, attrs); } } } diff --git a/src/extension/TeamCityVersion.cs b/src/extension/TeamCityVersion.cs index b0226f8..e6fb8e3 100644 --- a/src/extension/TeamCityVersion.cs +++ b/src/extension/TeamCityVersion.cs @@ -34,22 +34,26 @@ public TeamCityVersion(string version) { try { - if (!string.IsNullOrEmpty(version)) + if (string.IsNullOrEmpty(version)) { - var match = VersionRegex.Match(version); - if (match.Success) - { - int val; - if (int.TryParse(match.Groups[1].Value, out val)) - { - Major = val; - } + return; + } + + var match = VersionRegex.Match(version); + if (!match.Success) + { + return; + } - if (int.TryParse(match.Groups[3].Value, out val)) - { - Minor = val; - } - } + int val; + if (int.TryParse(match.Groups[1].Value, out val)) + { + Major = val; + } + + if (int.TryParse(match.Groups[3].Value, out val)) + { + Minor = val; } } catch @@ -58,19 +62,14 @@ public TeamCityVersion(string version) } } - public int Major { get; private set; } + private int Major { get; set; } - public int Minor { get; private set; } + private int Minor { get; set; } public int CompareTo(TeamCityVersion other) { var result = Major.CompareTo(other.Major); - if (result != 0) - { - return result; - } - - return Minor.CompareTo(other.Minor); + return result != 0 ? result : Minor.CompareTo(other.Minor); } public override string ToString() diff --git a/src/tests/ServiceMessageWriterTest.cs b/src/tests/ServiceMessageWriterTest.cs index 3dcaf21..0008679 100644 --- a/src/tests/ServiceMessageWriterTest.cs +++ b/src/tests/ServiceMessageWriterTest.cs @@ -1,4 +1,5 @@ -namespace NUnit.Engine.Listeners +// ReSharper disable StringLiteralTypo +namespace NUnit.Engine.Listeners { using Framework; diff --git a/src/tests/SuiteNameReplacerTest.cs b/src/tests/SuiteNameReplacerTest.cs index 34117b6..d7a97fa 100644 --- a/src/tests/SuiteNameReplacerTest.cs +++ b/src/tests/SuiteNameReplacerTest.cs @@ -1,5 +1,6 @@ namespace NUnit.Engine.Listeners { + using System.Diagnostics.CodeAnalysis; using Framework; [TestFixture] @@ -58,6 +59,7 @@ public void ShouldReplaceAssemblyName(string name, string suitePattern, string e Assert.AreEqual(expectedSuiteName, actualSuiteName); } + [SuppressMessage("ReSharper", "UnusedAutoPropertyAccessor.Local")] private class MyTeamCityInfo : ITeamCityInfo { public bool MetadataEnabled { get; set; } diff --git a/src/tests/TeamCityEventListener3IntegrationTests.cs b/src/tests/TeamCityEventListener3IntegrationTests.cs index 7e8f873..c80cf30 100644 --- a/src/tests/TeamCityEventListener3IntegrationTests.cs +++ b/src/tests/TeamCityEventListener3IntegrationTests.cs @@ -24,6 +24,7 @@ namespace NUnit.Engine.Listeners { using System; + using System.Diagnostics.CodeAnalysis; using System.IO; using System.Text; using Extensibility; @@ -420,6 +421,7 @@ private EventListener CreateInstance(ITeamCityInfo info = null) return TestUtil.CreateListener(_outputWriter, info); } + [SuppressMessage("ReSharper", "UnusedAutoPropertyAccessor.Local")] private class MyTeamCityInfo : ITeamCityInfo { public bool MetadataEnabled { get; set; } diff --git a/src/tests/TestUtil.cs b/src/tests/TestUtil.cs index ec9e1c4..a9e3d33 100644 --- a/src/tests/TestUtil.cs +++ b/src/tests/TestUtil.cs @@ -83,39 +83,37 @@ public static IEnumerable ConvertToMessages(IEnumerable lines) } } - if (inBlock) + if (!inBlock) { - fullLine.AppendLine(line); - if (line.Contains(FinishBlock)) - { - inBlock = false; - var nextLine = fullLine.ToString(); - var first = nextLine.IndexOf(StartBlock, StringComparison.InvariantCulture) + StartBlock.Length; - var last = nextLine.IndexOf(FinishBlock, StringComparison.InvariantCulture); - yield return CreateMessage(nextLine.Substring(first, last - first)); - } - } + continue; + } + + fullLine.AppendLine(line); + if (!line.Contains(FinishBlock)) + { + continue; + } + + inBlock = false; + var nextLine = fullLine.ToString(); + var first = nextLine.IndexOf(StartBlock, StringComparison.InvariantCulture) + StartBlock.Length; + var last = nextLine.IndexOf(FinishBlock, StringComparison.InvariantCulture); + yield return CreateMessage(nextLine.Substring(first, last - first)); } } private static string GetNamedAttr(string attrName, string attrValue) { - if (attrValue == null) - { - return string.Empty; - } - - return string.Format("{0}=\"{1}\"", attrName, attrValue); + return attrValue == null + ? string.Empty + : string.Format("{0}=\"{1}\"", attrName, attrValue); } private static string GetNamedElement(string elementName, string elementValue) { - if (elementValue == null) - { - return string.Empty; - } - - return string.Format("<{0}>{1}", elementName, elementValue); + return elementValue == null + ? string.Empty + : string.Format("<{0}>{1}", elementName, elementValue); } private static XmlNode CreateMessage(string text) From d4b3ab569601657fd11c3a6011abe7c0b97999a6 Mon Sep 17 00:00:00 2001 From: Nikolay Pyanikov Date: Thu, 14 Jul 2022 10:55:39 +0300 Subject: [PATCH 3/3] Update VS version in appveyor --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 56f2086..f91dca1 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,5 +1,5 @@ # base image -image: Visual Studio 2019 +image: Visual Studio 2022 build_script: - ps: .\build.ps1 -Target "Appveyor"