Skip to content
This repository was archived by the owner on Nov 7, 2019. It is now read-only.

Commit 6c17aad

Browse files
committed
Moved "guess the test runner" to validation
1 parent acff37d commit 6c17aad

File tree

5 files changed

+189
-216
lines changed

5 files changed

+189
-216
lines changed

src/SpecFlow.NetCore/AppConfig.cs

Lines changed: 103 additions & 127 deletions
Original file line numberDiff line numberDiff line change
@@ -1,101 +1,72 @@
1-
using System;
2-
using System.IO;
3-
using System.Linq;
4-
using System.Xml.Linq;
5-
using System.Xml.XPath;
6-
using Newtonsoft.Json;
7-
using Specflow.NetCore;
8-
using static System.Console;
9-
10-
namespace SpecFlow.NetCore
11-
{
12-
internal class AppConfig
1+
using System;
2+
using System.IO;
3+
using System.Linq;
4+
using System.Xml.Linq;
5+
using System.Xml.XPath;
6+
using Newtonsoft.Json;
7+
using Specflow.NetCore;
8+
using static System.Console;
9+
10+
namespace SpecFlow.NetCore
11+
{
12+
internal class AppConfig
1313
{
14-
#region Ignore the strange indentation; it is like that so the final file looks right.
15-
public const string SpecFlowSectionDefinitionType = "TechTalk.SpecFlow.Configuration.ConfigurationSectionHandler, TechTalk.SpecFlow";
16-
17-
public const string SpecFlowSectionDefinition = @" <configSections>
18-
<section name=""specFlow"" type=""" + SpecFlowSectionDefinitionType + @""" />
19-
</configSections>";
20-
21-
public const string SpecFlowSectionElement = "unitTestProvider";
22-
23-
public const string SpecFlowSection = @" <specFlow>
24-
<" + SpecFlowSectionElement + @" name=""{0}"" />
25-
</specFlow>";
26-
27-
public static string Content = $@"<?xml version=""1.0"" encoding=""utf-8""?>
28-
<configuration>
29-
{SpecFlowSectionDefinition}
30-
{SpecFlowSection}
14+
#region Ignore the strange indentation; it is like that so the final file looks right.
15+
public const string SpecFlowSectionDefinitionType = "TechTalk.SpecFlow.Configuration.ConfigurationSectionHandler, TechTalk.SpecFlow";
16+
17+
public const string SpecFlowSectionDefinition = @" <configSections>
18+
<section name=""specFlow"" type=""" + SpecFlowSectionDefinitionType + @""" />
19+
</configSections>";
20+
21+
public const string SpecFlowSectionElement = "unitTestProvider";
22+
23+
public const string SpecFlowSection = @" <specFlow>
24+
<" + SpecFlowSectionElement + @" name=""{0}"" />
25+
</specFlow>";
26+
27+
public static string Content = $@"<?xml version=""1.0"" encoding=""utf-8""?>
28+
<configuration>
29+
{SpecFlowSectionDefinition}
30+
{SpecFlowSection}
3131
</configuration>";
32-
#endregion
33-
34-
public string Path { get; }
35-
36-
public string TestFramework { get; }
37-
38-
public AppConfig(string path, string testFramework)
39-
{
40-
Path = path;
41-
TestFramework = testFramework;
42-
}
43-
44-
public static AppConfig CreateIn(DirectoryInfo directory, out string usedTestRunner, string testRunner = null)
45-
{
46-
if (string.IsNullOrWhiteSpace(testRunner))
47-
{
48-
testRunner = GuessUnitTestProvider(directory);
49-
}
50-
var config = new AppConfig(System.IO.Path.Combine(directory.FullName, "app.config"), testRunner);
51-
52-
WriteLine($@"Using test runner ""{testRunner}""");
53-
usedTestRunner = testRunner;
54-
if (File.Exists(config.Path))
55-
{
56-
config.ChangeTestProviderIfNeeded(testRunner);
57-
return config;
58-
}
59-
60-
Content = string.Format(Content, testRunner);
61-
WriteLine("Generating app.config");
62-
WriteLine(Content);
63-
WriteLine("Saving: " + config.Path);
64-
File.WriteAllText(config.Path, Content);
65-
66-
return config;
67-
}
68-
69-
public void ChangeTestProviderIfNeeded(string testRunner)
70-
{
71-
var file = XDocument.Load(Path);
32+
#endregion
33+
34+
public DirectoryInfo Directory { get; set; }
35+
public string Path => System.IO.Path.Combine(Directory.FullName, "app.config");
36+
public string TestFramework { get; }
37+
38+
public AppConfig(DirectoryInfo directory, string testFramework)
39+
{
40+
Directory = directory;
41+
TestFramework = testFramework;
42+
}
43+
44+
public static AppConfig CreateIn(DirectoryInfo directory, string testFramework = null)
45+
{
46+
if (string.IsNullOrWhiteSpace(testFramework))
47+
testFramework = GetProjectJsonTestRunner(directory);
48+
49+
var config = new AppConfig(directory, testFramework);
50+
51+
if (File.Exists(config.Path))
52+
return config;
53+
54+
Content = string.Format(Content, testFramework);
55+
WriteLine("Generating app.config");
56+
WriteLine(Content);
57+
WriteLine("Saving: " + config.Path);
58+
File.WriteAllText(config.Path, Content);
59+
60+
return config;
61+
}
62+
63+
private static string GetTestProvider(XDocument file)
64+
{
65+
return file.XPathEvaluate("string(/configuration/specFlow/unitTestProvider/@name)") as string;
66+
}
7267

73-
var currentTestRunner = GetTestProvider(file);
74-
if (!string.IsNullOrWhiteSpace(currentTestRunner) && testRunner == currentTestRunner)
75-
return;
76-
77-
var configXml = file.Descendants("configuration").FirstOrDefault();
78-
var specFlowXml = configXml?.Descendants("specFlow").FirstOrDefault();
79-
var unitTestProviderXml = specFlowXml?.Descendants("unitTestProvider").FirstOrDefault();
80-
if (unitTestProviderXml != null)
81-
{
82-
unitTestProviderXml.Attribute("name").Value = testRunner;
83-
WriteLine("unitTestProviderXml Name attribute = " + unitTestProviderXml.Attribute("name").Value);
84-
}
85-
using (var writer = File.CreateText(Path))
86-
{
87-
file.Save(writer);
88-
writer.Flush();
89-
}
90-
}
91-
92-
private static string GetTestProvider(XDocument file)
93-
{
94-
return file.XPathEvaluate("string(/configuration/specFlow/unitTestProvider/@name)") as string;
95-
}
96-
97-
public void Validate()
98-
{
68+
public void Validate()
69+
{
9970
WriteLine("Validating app.config.");
10071

10172
// I would rather use the ConfigurationBuilder, but as of beta8 it fails to read an element without
@@ -104,35 +75,40 @@ public void Validate()
10475
// .AddXmlFile(path)
10576
// .Build();
10677

107-
var file = XDocument.Load(Path);
108-
109-
var definitionType = file.XPathEvaluate("string(/configuration/configSections/section[@name='specFlow']/@type)") as string;
110-
111-
if (definitionType != SpecFlowSectionDefinitionType)
112-
throw new Exception("Couldn't find required SpecFlow section handler in app.config. Example:\n" + SpecFlowSectionDefinition);
113-
114-
var testProvider = GetTestProvider(file);
115-
116-
if (string.IsNullOrWhiteSpace(testProvider))
117-
throw new Exception("Couldn't find required SpecFlow element in app.config. Example:\n" + SpecFlowSection);
118-
}
119-
120-
private static string GuessUnitTestProvider(DirectoryInfo directory)
121-
{
122-
WriteLine($"Guessing test runner from project.json. You can always force a specific test runner using {Args.TestRunnerArgName}");
123-
var foundProjectJson = directory.GetFiles().SingleOrDefault(f => f.Name == "project.json");
124-
if (foundProjectJson != null)
125-
{
126-
var projectJson = JsonConvert.DeserializeObject<ProjectJson>(File.ReadAllText(foundProjectJson.FullName));
127-
if (projectJson.TestRunner != null)
128-
{
129-
return projectJson.TestRunner;
130-
}
131-
WriteLine($@"No ""testRunner"" element found in { foundProjectJson.FullName }. Defaulting to xUnit.");
132-
return "xUnit";
133-
}
134-
WriteLine("No project json found. Defaulting to xUnit.");
135-
return "xUnit";
136-
}
137-
}
138-
}
78+
var file = XDocument.Load(Path);
79+
80+
var definitionType = file.XPathEvaluate("string(/configuration/configSections/section[@name='specFlow']/@type)") as string;
81+
82+
if (definitionType != SpecFlowSectionDefinitionType)
83+
throw new Exception("Couldn't find required SpecFlow section handler in app.config. Example:\n" + SpecFlowSectionDefinition);
84+
85+
var testProvider = GetTestProvider(file);
86+
87+
if (string.IsNullOrWhiteSpace(testProvider))
88+
throw new Exception("Couldn't find required SpecFlow element in app.config. Example:\n" + SpecFlowSection);
89+
90+
var projectJsonTestRunner = GetProjectJsonTestRunner(Directory);
91+
92+
if (string.IsNullOrWhiteSpace(projectJsonTestRunner))
93+
return;
94+
95+
if (!TestFramework.Equals(projectJsonTestRunner, StringComparison.OrdinalIgnoreCase))
96+
throw new Exception($"App.config test provider doesn't match the project.json test runner: {TestFramework} vs {projectJsonTestRunner}");
97+
}
98+
99+
private static string GetProjectJsonTestRunner(DirectoryInfo directory)
100+
{
101+
var foundProjectJson = directory.GetFiles().SingleOrDefault(f => f.Name == "project.json");
102+
103+
if (foundProjectJson == null)
104+
throw new Exception("Can't find project.json in directory: " + directory.FullName);
105+
106+
var projectJson = JsonConvert.DeserializeObject<ProjectJson>(File.ReadAllText(foundProjectJson.FullName));
107+
108+
if (string.IsNullOrWhiteSpace(projectJson.TestRunner))
109+
throw new Exception("project.json doesn't have a testRunner.");
110+
111+
return projectJson.TestRunner;
112+
}
113+
}
114+
}

src/SpecFlow.NetCore/Args.cs

Lines changed: 70 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,73 +1,73 @@
1-
using System;
2-
using System.IO;
3-
using System.Linq;
4-
using static System.Console;
5-
6-
namespace Specflow.NetCore
7-
{
8-
public class Args
9-
{
10-
public const string SpecFlowPathArgName = "--specflow-path";
11-
public const string WorkingDirectoryArgName = "--working-directory";
12-
public const string TestRunnerArgName = "--test-framework";
13-
14-
public string SpecFlowPath { get; }
15-
public DirectoryInfo WorkingDirectory { get; }
16-
public string TestRunner { get; }
17-
18-
public Args(string[] args)
19-
{
20-
WorkingDirectory = new DirectoryInfo(Directory.GetCurrentDirectory());
21-
22-
if (args == null || !args.Any())
23-
return;
24-
25-
// Very basic arg parsing:
26-
// - Assume odd elements are arg names.
27-
// - Assume even elements are arg values.
28-
// - Paths with spaces will probably blow up.
29-
// - Duplicates, last one wins.
30-
31-
for (var i = 0; i < args.Length; i++)
32-
{
33-
if (IsOdd(i))
34-
continue;
35-
36-
if (i + 1 >= args.Length)
37-
throw new Exception("Uneven arguments");
38-
39-
var name = args[i];
40-
var value = args[i + 1];
41-
42-
switch (name)
43-
{
44-
case SpecFlowPathArgName:
45-
SpecFlowPath = value;
46-
break;
47-
48-
case WorkingDirectoryArgName:
49-
if (!Directory.Exists(value))
50-
throw new Exception("Working directory doesn't exist: " + value);
51-
WorkingDirectory = new DirectoryInfo(value);
1+
using System;
2+
using System.IO;
3+
using System.Linq;
4+
using static System.Console;
5+
6+
namespace Specflow.NetCore
7+
{
8+
internal class Args
9+
{
10+
public const string SpecFlowPathArgName = "--specflow-path";
11+
public const string WorkingDirectoryArgName = "--working-directory";
12+
public const string TestFrameworkArgName = "--test-framework";
13+
14+
public string SpecFlowPath { get; }
15+
public DirectoryInfo WorkingDirectory { get; }
16+
public string TestFramework { get; }
17+
18+
public Args(string[] args)
19+
{
20+
WorkingDirectory = new DirectoryInfo(Directory.GetCurrentDirectory());
21+
22+
if (args == null || !args.Any())
23+
return;
24+
25+
// Very basic arg parsing:
26+
// - Assume odd elements are arg names.
27+
// - Assume even elements are arg values.
28+
// - Paths with spaces will probably blow up.
29+
// - Duplicates, last one wins.
30+
31+
for (var i = 0; i < args.Length; i++)
32+
{
33+
if (IsOdd(i))
34+
continue;
35+
36+
if (i + 1 >= args.Length)
37+
throw new Exception("Uneven arguments");
38+
39+
var name = args[i];
40+
var value = args[i + 1];
41+
42+
switch (name)
43+
{
44+
case SpecFlowPathArgName:
45+
SpecFlowPath = value;
46+
break;
47+
48+
case WorkingDirectoryArgName:
49+
if (!Directory.Exists(value))
50+
throw new Exception("Working directory doesn't exist: " + value);
51+
WorkingDirectory = new DirectoryInfo(value);
5252
break;
5353

54-
case TestRunnerArgName:
55-
TestRunner = value;
56-
break;
57-
58-
default:
59-
throw new Exception("Unknown argument: " + name);
60-
}
61-
}
62-
63-
WriteLine("SpecFlowPath: " + SpecFlowPath);
64-
WriteLine("WorkingDirectory: " + WorkingDirectory.FullName);
65-
WriteLine("Test runner: " + WorkingDirectory.FullName);
66-
}
67-
68-
private bool IsOdd(int i)
69-
{
70-
return i % 2 != 0;
71-
}
72-
}
54+
case TestFrameworkArgName:
55+
TestFramework = value;
56+
break;
57+
58+
default:
59+
throw new Exception("Unknown argument: " + name);
60+
}
61+
}
62+
63+
WriteLine("SpecFlowPath: " + SpecFlowPath);
64+
WriteLine("WorkingDirectory: " + WorkingDirectory.FullName);
65+
WriteLine("TestFramework: " + TestFramework);
66+
}
67+
68+
private bool IsOdd(int i)
69+
{
70+
return i % 2 != 0;
71+
}
72+
}
7373
}

0 commit comments

Comments
 (0)