This repository has been archived by the owner on Jan 21, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 6
/
Core.fs
161 lines (136 loc) · 6.48 KB
/
Core.fs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
module FifteenBelow.NUnitMerger.Core
open System
open System.IO
open System.Xml
open System.Xml.Linq
let inline (!!) arg =
( ^a : (static member op_Implicit : ^b -> ^a) arg)
let getInt str =
Convert.ToInt32(str, System.Globalization.CultureInfo.InvariantCulture)
let getDouble str =
Convert.ToDouble(str, System.Globalization.CultureInfo.InvariantCulture)
type ResultSummary =
{
total : int
errors : int
failures : int
notrun : int
inconclusive : int
ignored : int
skipped : int
invalid : int
datetime : DateTime
}
let GetTestSummary (xDoc : XDocument) =
let tr = xDoc.Element(!!"test-results")
{
total = tr.Attribute(!!"total").Value |> getInt
errors = tr.Attribute(!!"errors").Value |> getInt
failures = tr.Attribute(!!"failures").Value |> getInt
notrun = tr.Attribute(!!"not-run").Value |> getInt
inconclusive = tr.Attribute(!!"inconclusive").Value |> getInt
ignored = tr.Attribute(!!"ignored").Value |> getInt
skipped = tr.Attribute(!!"skipped").Value |> getInt
invalid = tr.Attribute(!!"invalid").Value |> getInt
datetime = String.concat " " [tr.Attribute(!!"date").Value;tr.Attribute(!!"time").Value] |> (fun s -> DateTime.Parse(s, System.Globalization.CultureInfo.InvariantCulture))
}
let CreateTestSummaryElement summary =
XElement.Parse (sprintf "<test-results name=\"Merged results\" total=\"%d\" errors=\"%d\" failures=\"%d\" not-run=\"%d\" inconclusive=\"%d\" skipped=\"%d\" invalid=\"%d\" date=\"%s\" time=\"%s\" />" summary.total summary.errors summary.failures summary.notrun summary.inconclusive summary.skipped summary.invalid (summary.datetime.ToString("yyyy-MM-dd")) (summary.datetime.ToString("HH:mm:ss")))
type environment =
{
nunitversion : string
clrversion : string
osversion : string
platform : string
cwd : string
machinename : string
user : string
userdomain : string
}
let GetEnvironment (xDoc : XDocument) =
let env = xDoc.Element(!!"test-results").Element(!!"environment")
{
nunitversion = env.Attribute(!!"nunit-version").Value
clrversion = env.Attribute(!!"clr-version").Value
osversion = env.Attribute(!!"os-version").Value
platform = env.Attribute(!!"platform").Value
cwd = env.Attribute(!!"cwd").Value
machinename = env.Attribute(!!"machine-name").Value
user = env.Attribute(!!"user").Value
userdomain = env.Attribute(!!"user-domain").Value
}
let CreateEnvironment environment =
XElement.Parse (sprintf "<environment nunit-version=\"%s\" clr-version=\"%s\" os-version=\"%s\" platform=\"%s\" cwd=\"%s\" machine-name=\"%s\" user=\"%s\" user-domain=\"%s\" />" environment.nunitversion environment.clrversion environment.osversion environment.platform environment.cwd environment.machinename environment.user environment.userdomain)
type culture =
{
currentculture : string
currentuiculture : string
}
let GetCulture (xDoc : XDocument) =
let culture = xDoc.Element(!!"test-results").Element(!!"culture-info")
{
currentculture = culture.Attribute(!!"current-culture").Value
currentuiculture = culture.Attribute(!!"current-uiculture").Value
}
let CreateCulture culture =
XElement.Parse (sprintf "<culture-info current-culture=\"%s\" current-uiculture=\"%s\" />" culture.currentculture culture.currentuiculture)
let FoldAssemblyToProjectTuple agg (assembly : XElement) =
let result, time, asserts = agg
let outResult =
if assembly.Attribute(!!"result").Value = "Failure" then "Failure"
elif assembly.Attribute(!!"result").Value = "Inconclusive" && result = "Success" then "Inconclusive"
else result
(outResult, time + getDouble (assembly.Attribute(!!"time").Value), asserts + getInt (assembly.Attribute(!!"asserts").Value))
let TestProjectSummary assemblies =
assemblies
|> Seq.fold FoldAssemblyToProjectTuple ("Success", 0.0, 0)
let CreateTestProjectNode assemblies =
let result, time, asserts = TestProjectSummary assemblies
let projectEl = XElement.Parse (sprintf "<test-suite type=\"Test Project\" name=\"\" executed=\"True\" result=\"%s\" time=\"%f\" asserts=\"%d\" />" result time asserts)
let results = XElement.Parse ("<results/>")
results.Add (assemblies |> Seq.toArray)
projectEl.Add results
projectEl
let MergeTestSummary agg summary =
{ agg with
total = agg.total + summary.total
errors = agg.errors + summary.errors
failures = agg.failures + summary.failures
notrun = agg.notrun + summary.notrun
inconclusive = agg.inconclusive + summary.inconclusive
ignored = agg.ignored + summary.ignored
skipped = agg.skipped + summary.skipped
invalid = agg.invalid + summary.invalid
datetime = Seq.min [agg.datetime;summary.datetime]
}
let GetTestAssemblies (xDoc : XDocument) =
xDoc.Descendants()
|> Seq.filter (fun el -> el.Name = (!!"test-suite") && el.Attribute(!!"type").Value = "Assembly")
let GetXDocs directory filter =
Directory.GetFiles(directory, filter, SearchOption.AllDirectories)
|> Seq.map (fun fileName -> XDocument.Parse(File.ReadAllText(fileName)))
let Folder state xDoc =
let summary, environment, culture, assemblies = state
// Sanity check!
if environment <> (GetEnvironment xDoc) || culture <> (GetCulture xDoc) then printf "Unmatched environment and/or cultures detected: some of theses results files are not from the same test run."
(MergeTestSummary (GetTestSummary xDoc) summary, environment, culture, Seq.append assemblies (GetTestAssemblies xDoc))
let FoldDocs docs =
let state = (Seq.head docs |> GetTestSummary, Seq.head docs |> GetEnvironment, Seq.head docs |> GetCulture, Seq.empty)
Seq.fold Folder state docs
let CreateMerged state =
let summary, environment, culture, assemblies = state
let results = (CreateTestSummaryElement summary)
results.Add [CreateEnvironment environment;CreateCulture culture;CreateTestProjectNode assemblies]
results
let WriteMergedNunitResults (directory, filter, outfile) =
GetXDocs directory filter
|> FoldDocs
|> CreateMerged
|> fun x -> File.WriteAllText(outfile, x.ToString())
let AllSucceeded xDocs =
xDocs
|> Seq.map GetTestAssemblies
|> Seq.concat
|> Seq.map (fun assembly -> assembly.Attribute(!!"result").Value)
|> Seq.map (fun x -> x <> "Failure")
|> Seq.reduce (&&)