-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathSpecFlowParserHelper.cs
More file actions
176 lines (160 loc) · 6.48 KB
/
SpecFlowParserHelper.cs
File metadata and controls
176 lines (160 loc) · 6.48 KB
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
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Gherkin.Ast;
using TechTalk.SpecFlow.Parser;
namespace SpecFlow.xUnitAdapter.SpecFlowPlugin
{
public static class SpecFlowParserHelper
{
private static SpecFlowGherkinParser CreateParser()
{
var parser = new SpecFlowGherkinParser(new CultureInfo("en-US")); //TODO: use specflow configuration
return parser;
}
public static async Task<SpecFlowDocument> ParseSpecFlowDocumentAsync(string featureFilePath)
{
var fileContent = await ReadAllTextAsync(featureFilePath);
var parser = CreateParser();
var gherkinDocument = parser.Parse(new StringReader(fileContent), featureFilePath);
return gherkinDocument;
}
public static SpecFlowDocument ParseSpecFlowDocument(string featureFilePath)
{
using (var stream = new FileStream(featureFilePath, FileMode.Open))
using (var reader = new StreamReader(stream))
{
var parser = CreateParser();
var gherkinDocument = parser.Parse(reader, featureFilePath);
return gherkinDocument;
}
}
private static async Task<string> ReadAllTextAsync(string filePath)
{
using (var reader = File.OpenText(filePath))
{
return await reader.ReadToEndAsync();
}
}
public static IEnumerable<string> GetTags(this IEnumerable<Tag> tagList)
{
if (tagList == null)
yield break;
foreach (var tag in tagList)
{
yield return tag.Name.TrimStart('@');
}
}
public static string GetExampleRowId(ScenarioOutline scenarioOutline, TableRow exampleRow)
{
int exampleRowId = 0;
foreach (var row in scenarioOutline.Examples.SelectMany(example => example.TableBody))
{
++exampleRowId;
if (exampleRow == row)
return exampleRowId.ToString();
}
throw new InvalidOperationException("Unable to find example row");
}
public static bool GetExampleRowById(ScenarioOutline scenarioOutline, string exampleRowId, out Examples example, out TableRow exampleRow)
{
int id = 0;
foreach (var ex in scenarioOutline.Examples)
{
foreach (var row in ex.TableBody)
{
++id;
if (id.ToString() == exampleRowId)
{
example = ex;
exampleRow = row;
return true;
}
}
}
example = null;
exampleRow = null;
return false;
}
public static Dictionary<string, string> GetScenarioOutlineParametersById(ScenarioOutline scenarioOutline, string exampleRowId)
{
int id = 0;
foreach (var example in scenarioOutline.Examples)
{
foreach (var row in example.TableBody)
{
++id;
if (id.ToString() == exampleRowId)
return GetScenarioOutlineParameters(example, row);
}
}
return null;
}
public static Dictionary<string, string> GetScenarioOutlineParameters(Examples example, TableRow exampleRow)
{
return example.TableHeader.Cells
.Zip(exampleRow.Cells, (keyCell, valueCell) => new { Key = keyCell.Value, valueCell.Value })
.ToDictionary(arg => arg.Key, arg => arg.Value);
}
public static Scenario CreateScenario(ScenarioOutline scenarioOutline, Examples example, TableRow exampleRow)
{
var parameters = GetScenarioOutlineParameters(example, exampleRow);
var steps = new List<Step>();
var tags = new List<Tag>();
tags.AddRange(scenarioOutline.Tags);
tags.AddRange(example.Tags);
foreach (var scenarioOutlineStep in scenarioOutline.Steps.Cast<SpecFlowStep>())
{
string stepText = Interpolate(scenarioOutlineStep.Text, parameters);
var step = new SpecFlowStep(scenarioOutlineStep.Location, scenarioOutlineStep.Keyword, stepText,
CreatePickleArguments(scenarioOutlineStep.Argument, parameters),
scenarioOutlineStep.StepKeyword, scenarioOutlineStep.ScenarioBlock);
steps.Add(step);
}
return new Scenario(tags.ToArray(), scenarioOutline.Location, scenarioOutline.Keyword, scenarioOutline.Name,
scenarioOutline.Description, steps.ToArray());
}
private static StepArgument CreatePickleArguments(StepArgument argument, Dictionary<string,string> parameters)
{
if (argument == null) return null;
if (argument is DataTable)
{
DataTable t = (DataTable)argument;
var rows = t.Rows;
var newRows = new List<TableRow>(rows.Count());
foreach (var row in rows)
{
var cells = row.Cells;
var newCells = new List<TableCell>();
foreach (var cell in cells)
{
newCells.Add(new TableCell(cell.Location, Interpolate(cell.Value, parameters)));
}
newRows.Add(new TableRow(row.Location, newCells.ToArray()));
}
return new DataTable(newRows.ToArray());
}
if (argument is DocString)
{
DocString ds = (DocString)argument;
return new DocString(
ds.Location,
ds.ContentType,
Interpolate(ds.Content, parameters)
);
}
throw new InvalidOperationException("Unexpected argument type: " + argument);
}
private static string Interpolate(string name, Dictionary<string, string> parameters)
{
foreach (var parameter in parameters)
{
name = name.Replace("<" + parameter.Key + ">", parameter.Value);
}
return name;
}
}
}