From fdfecbdff422d4eaf2f53beefc72bf403b49bfc5 Mon Sep 17 00:00:00 2001 From: Steve Gilham Date: Wed, 31 Jan 2018 10:31:10 +0000 Subject: [PATCH] Localization for the recorder --- AltCover.Recorder/AltCover.Recorder.fsproj | 1 + AltCover.Recorder/AltCover.Shadow.fsproj | 1 + AltCover.Recorder/Recorder.fs | 23 +++- AltCover.Recorder/Strings.resx | 126 +++++++++++++++++++++ Build/targets.fsx | 2 +- Shadow.Tests/Shadow.Tests.fs | 93 +++++++-------- 6 files changed, 198 insertions(+), 48 deletions(-) create mode 100644 AltCover.Recorder/Strings.resx diff --git a/AltCover.Recorder/AltCover.Recorder.fsproj b/AltCover.Recorder/AltCover.Recorder.fsproj index 2407f00b7..ab9790756 100644 --- a/AltCover.Recorder/AltCover.Recorder.fsproj +++ b/AltCover.Recorder/AltCover.Recorder.fsproj @@ -77,6 +77,7 @@ + diff --git a/AltCover.Recorder/AltCover.Shadow.fsproj b/AltCover.Recorder/AltCover.Shadow.fsproj index 29a6f6ca9..5c58da638 100644 --- a/AltCover.Recorder/AltCover.Shadow.fsproj +++ b/AltCover.Recorder/AltCover.Shadow.fsproj @@ -68,6 +68,7 @@ + diff --git a/AltCover.Recorder/Recorder.fs b/AltCover.Recorder/Recorder.fs index 1e7ee3887..25dadf03c 100644 --- a/AltCover.Recorder/Recorder.fs +++ b/AltCover.Recorder/Recorder.fs @@ -5,10 +5,28 @@ namespace AltCover.Recorder open System open System.Collections.Generic +open System.Reflection +open System.Resources open System.Runtime.CompilerServices module Instance = + // Can't hard-code what with .net-core and .net-core tests as well as classic .net + // all giving this a different namespace + let private resource = Assembly.GetExecutingAssembly().GetManifestResourceNames() + |> Seq.map (fun s -> s.Substring(0, s.Length - 10)) // trim ".resources" + |> Seq.find (fun n -> n.EndsWith("Strings", StringComparison.Ordinal)) + let internal resources = ResourceManager(resource , Assembly.GetExecutingAssembly()) + + let GetResource s = + [ + System.Globalization.CultureInfo.CurrentUICulture.Name + System.Globalization.CultureInfo.CurrentUICulture.Parent.Name + "en" + ] + |> Seq.map (fun l -> resources.GetString(s + "." + l)) + |> Seq.tryFind (String.IsNullOrEmpty >> not) + /// /// Gets the location of coverage xml file /// This property's IL code is modified to store actual file location @@ -31,7 +49,7 @@ module Instance = /// /// Interlock for report instances /// - let private mutex = new System.Threading.Mutex(false, Token + ".mutex"); + let internal mutex = new System.Threading.Mutex(false, Token + ".mutex"); /// /// Reporting back to the mother-ship; only on the .net core build @@ -76,7 +94,8 @@ module Instance = Visits.Clear() WithMutex (fun own -> let delta = Counter.DoFlush own counts ReportFile - Console.Out.WriteLine("Coverage statistics flushing took {0:N} seconds", delta.TotalSeconds) + GetResource "Coverage statistics flushing took {0:N} seconds" + |> Option.iter (fun s -> Console.Out.WriteLine(s, delta.TotalSeconds)) )) let internal TraceVisit moduleId hitPointId = diff --git a/AltCover.Recorder/Strings.resx b/AltCover.Recorder/Strings.resx new file mode 100644 index 000000000..3da10519a --- /dev/null +++ b/AltCover.Recorder/Strings.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Coverage statistics flushing took {0:N} seconds + + + Kovraj statistika skribado prenis {0:N} sekundojn + + \ No newline at end of file diff --git a/Build/targets.fsx b/Build/targets.fsx index b5891d7a6..14da83713 100644 --- a/Build/targets.fsx +++ b/Build/targets.fsx @@ -537,7 +537,7 @@ Target "Packaging" (fun _ -> |> Seq.filter (fun n -> n.EndsWith(".fs") || n.EndsWith(".core.fsproj") || n.EndsWith(".resx")) |> Seq.toList); ((!! "./AltCover.Recorder/*") - |> Seq.filter (fun n -> n.EndsWith(".fs") || n.EndsWith(".core.fsproj")) + |> Seq.filter (fun n -> n.EndsWith(".fs") || n.EndsWith(".core.fsproj") || n.EndsWith(".resx")) |> Seq.toList); ((!! "./_Generated/*") |> Seq.toList) diff --git a/Shadow.Tests/Shadow.Tests.fs b/Shadow.Tests/Shadow.Tests.fs index 0815c1ff4..b447a6912 100644 --- a/Shadow.Tests/Shadow.Tests.fs +++ b/Shadow.Tests/Shadow.Tests.fs @@ -24,6 +24,7 @@ open System.Xml open AltCover.Recorder open NUnit.Framework +open System.Threading [] type AltCoverTests() = class @@ -319,54 +320,56 @@ type AltCoverTests() = class [] member self.FlushLeavesExpectedTraces() = - let saved = Console.Out - let here = Directory.GetCurrentDirectory() - let where = Assembly.GetExecutingAssembly().Location |> Path.GetDirectoryName - let unique = Path.Combine(where, Guid.NewGuid().ToString()) try - Instance.Visits.Clear() - use stdout = new StringWriter() - Console.SetOut stdout - Directory.CreateDirectory(unique) |> ignore - Directory.SetCurrentDirectory(unique) + let saved = Console.Out + let here = Directory.GetCurrentDirectory() + let where = Assembly.GetExecutingAssembly().Location |> Path.GetDirectoryName + let unique = Path.Combine(where, Guid.NewGuid().ToString()) + try + Instance.Visits.Clear() + use stdout = new StringWriter() + Console.SetOut stdout + Directory.CreateDirectory(unique) |> ignore + Directory.SetCurrentDirectory(unique) - Counter.measureTime <- DateTime.ParseExact("2017-12-29T16:33:40.9564026+00:00", "o", null) - use stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(self.resource) - let size = int stream.Length - let buffer = Array.create size 0uy - Assert.That (stream.Read(buffer, 0, size), Is.EqualTo size) - do - use worker = new FileStream(Instance.ReportFile, FileMode.CreateNew) - worker.Write(buffer, 0, size) - () + Counter.measureTime <- DateTime.ParseExact("2017-12-29T16:33:40.9564026+00:00", "o", null) + use stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(self.resource) + let size = int stream.Length + let buffer = Array.create size 0uy + Assert.That (stream.Read(buffer, 0, size), Is.EqualTo size) + do + use worker = new FileStream(Instance.ReportFile, FileMode.CreateNew) + worker.Write(buffer, 0, size) + () - let payload = Dictionary() - [0..9 ] - |> Seq.iter(fun i -> payload.[i] <- (i+1)) - Instance.Visits.["f6e3edb3-fb20-44b3-817d-f69d1a22fc2f"] <- payload + let payload = Dictionary() + [0..9 ] + |> Seq.iter(fun i -> payload.[i] <- (i+1)) + Instance.Visits.["f6e3edb3-fb20-44b3-817d-f69d1a22fc2f"] <- payload - Instance.FlushCounter true () - - let head = "Coverage statistics flushing took " - let tail = " seconds\n" - let recorded = stdout.ToString().Replace("\r\n","\n") - Assert.That (recorded.StartsWith(head, StringComparison.Ordinal)) - Assert.That (recorded.EndsWith(tail, StringComparison.Ordinal)) - use worker' = new FileStream(Instance.ReportFile, FileMode.Open) - let after = XmlDocument() - after.Load worker' - Assert.That( after.SelectNodes("//seqpnt") - |> Seq.cast - |> Seq.map (fun x -> x.GetAttribute("visitcount")), - Is.EquivalentTo [ "11"; "10"; "9"; "8"; "7"; "6"; "4"; "3"; "2"; "1"]) - finally - if File.Exists Instance.ReportFile then File.Delete Instance.ReportFile - Instance.Visits.Clear() - Console.SetOut saved - Directory.SetCurrentDirectory(here) - try - Directory.Delete(unique) - with - | :? IOException -> () + Instance.FlushCounter true () + let head = "Coverage statistics flushing took " + let tail = " seconds\n" + let recorded = stdout.ToString().Replace("\r\n","\n") + Assert.That (recorded.StartsWith(head, StringComparison.Ordinal)) + Assert.That (recorded.EndsWith(tail, StringComparison.Ordinal)) + use worker' = new FileStream(Instance.ReportFile, FileMode.Open) + let after = XmlDocument() + after.Load worker' + Assert.That( after.SelectNodes("//seqpnt") + |> Seq.cast + |> Seq.map (fun x -> x.GetAttribute("visitcount")), + Is.EquivalentTo [ "11"; "10"; "9"; "8"; "7"; "6"; "4"; "3"; "2"; "1"]) + finally + if File.Exists Instance.ReportFile then File.Delete Instance.ReportFile + Instance.Visits.Clear() + Console.SetOut saved + Directory.SetCurrentDirectory(here) + try + Directory.Delete(unique) + with + | :? IOException -> () + with + | :? AbandonedMutexException -> Instance.mutex.ReleaseMutex() end \ No newline at end of file