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+ }
0 commit comments