public override Regex GetTestPattern(ReferencedFile referencedFile, string testFileText, ChutzpahTestSettingsFile settings) { var mochaFrameworkDefinition = MochaDefinition.GetInterfaceType(settings, referencedFile.Path, testFileText); var isCoffeeFile = referencedFile.Path.EndsWith(Constants.CoffeeScriptExtension, StringComparison.OrdinalIgnoreCase); switch (mochaFrameworkDefinition) { case Constants.MochaQunitInterface: return isCoffeeFile ? RegexPatterns.MochaTddOrQunitTestRegexCoffeeScript : RegexPatterns.MochaTddOrQunitTestRegexJavaScript; case Constants.MochaBddInterface: return isCoffeeFile ? RegexPatterns.MochaBddTestRegexCoffeeScript : RegexPatterns.MochaBddTestRegexJavaScript; case Constants.MochaTddInterface: return isCoffeeFile ? RegexPatterns.MochaTddOrQunitTestRegexCoffeeScript : RegexPatterns.MochaTddOrQunitTestRegexJavaScript; case Constants.MochaExportsInterface: return isCoffeeFile ? RegexPatterns.MochaExportsTestRegexCoffeeScript : RegexPatterns.MochaExportsTestRegexJavaScript; default: return isCoffeeFile ? RegexPatterns.MochaBddTestRegexCoffeeScript : RegexPatterns.MochaBddTestRegexJavaScript; } }
public static string GetInterfaceType(ChutzpahTestSettingsFile chutzpahTestSettings, string testFilePath, string testFileText) { if(!string.IsNullOrEmpty(chutzpahTestSettings.MochaInterface) && knownInterfaces.Contains(chutzpahTestSettings.MochaInterface,StringComparer.OrdinalIgnoreCase)) { return chutzpahTestSettings.MochaInterface.ToLowerInvariant(); } var isCoffeeFile = testFilePath.EndsWith(Constants.CoffeeScriptExtension, StringComparison.OrdinalIgnoreCase); if (isCoffeeFile) { if (RegexPatterns.MochaBddTestRegexCoffeeScript.IsMatch(testFileText)) return Constants.MochaBddInterface; if (RegexPatterns.MochaTddOrQunitTestRegexCoffeeScript.IsMatch(testFileText)) { return RegexPatterns.MochaTddSuiteRegexCoffeeScript.IsMatch(testFileText) ? Constants.MochaTddInterface : Constants.MochaQunitInterface; } if (RegexPatterns.MochaExportsTestRegexCoffeeScript.IsMatch(testFileText)) return Constants.MochaExportsInterface; } else { if (RegexPatterns.MochaBddTestRegexJavaScript.IsMatch(testFileText)) return Constants.MochaBddInterface; if (RegexPatterns.MochaTddOrQunitTestRegexJavaScript.IsMatch(testFileText)) { return RegexPatterns.MochaTddSuiteRegexJavaScript.IsMatch(testFileText) ? Constants.MochaTddInterface : Constants.MochaQunitInterface; } if (RegexPatterns.MochaExportsTestRegexJavaScript.IsMatch(testFileText)) return Constants.MochaExportsInterface; } return Constants.MochaBddInterface; }
public void Process(IFrameworkDefinition frameworkDefinition, ReferencedFile referencedFile, string testFileText, ChutzpahTestSettingsFile settings) { if (!referencedFile.IsFileUnderTest) { return; } var regExp = settings.TestPatternRegex ?? GetTestPattern(referencedFile,testFileText, settings); var lines = fileSystem.GetLines(referencedFile.Path); int lineNum = 1; foreach (var line in lines) { var match = regExp.Match(line); while (match.Success) { var testNameGroup = match.Groups["TestName"]; var testName = testNameGroup.Value; if (!string.IsNullOrWhiteSpace(testName)) { referencedFile.FilePositions.Add(lineNum, testNameGroup.Index + 1, testName); } match = match.NextMatch(); } lineNum++; } }
private string GetTestHarnessTemplatePath(IFrameworkDefinition definition, ChutzpahTestSettingsFile chutzpahTestSettings) { string templatePath = null; if (!string.IsNullOrEmpty(chutzpahTestSettings.CustomTestHarnessPath)) { // If CustomTestHarnessPath is absolute path then Path.Combine just returns it var harnessPath = Path.Combine(chutzpahTestSettings.SettingsFileDirectory, chutzpahTestSettings.CustomTestHarnessPath); var fullPath = fileProbe.FindFilePath(harnessPath); if (fullPath != null) { ChutzpahTracer.TraceInformation("Using Custom Test Harness from {0}", fullPath); templatePath = fullPath; } else { ChutzpahTracer.TraceError("Cannot find Custom Test Harness at {0}", chutzpahTestSettings.CustomTestHarnessPath); } } if (templatePath == null) { templatePath = fileProbe.GetPathInfo(Path.Combine(Constants.TestFileFolder, definition.GetTestHarness(chutzpahTestSettings))).FullPath; ChutzpahTracer.TraceInformation("Using builtin Test Harness from {0}", templatePath); } return templatePath; }
private void SetupAmdPathsIfNeeded(ChutzpahTestSettingsFile chutzpahTestSettings, List<ReferencedFile> referencedFiles, string testHarnessDirectory) { if (chutzpahTestSettings.TestHarnessReferenceMode == TestHarnessReferenceMode.AMD) { referenceProcessor.SetupAmdFilePaths(referencedFiles, testHarnessDirectory, chutzpahTestSettings); } }
private void ProcessTransforms(ChutzpahTestSettingsFile settings, TestCaseSummary overallSummary, TransformResult results) { // Do this here per settings file in case an individual transformer has any associated state // - we want them fresh var knownTransforms = transformerProvider .GetTransformers(fileSystem) .ToDictionary(x => x.Name, x => x, StringComparer.InvariantCultureIgnoreCase); foreach (var transformConfig in settings.Transforms) { SummaryTransformer transform = null; if (knownTransforms.TryGetValue(transformConfig.Name, out transform)) { var outputPath = transformConfig.Path; if (!fileSystem.IsPathRooted(outputPath) && !string.IsNullOrWhiteSpace(transformConfig.SettingsFileDirectory)) { outputPath = fileSystem.GetFullPath(Path.Combine(transformConfig.SettingsFileDirectory, outputPath)); } // TODO: In future, this would ideally split out the summary to just those parts // relevant to the files associated with the settings file being handled transform.Transform(overallSummary, outputPath); results.AddResult(transform.Name, outputPath); } } }
public override Regex GetTestPattern(ReferencedFile referencedFile, string testFileText, ChutzpahTestSettingsFile settings) { var isCoffeeFile = referencedFile.Path.EndsWith(Constants.CoffeeScriptExtension, StringComparison.OrdinalIgnoreCase); var regExp = isCoffeeFile ? RegexPatterns.QUnitTestRegexCoffeeScript : RegexPatterns.QUnitTestRegexJavaScript; return regExp; }
public override IDictionary<string, string> GenerateCompiledSources(IEnumerable<ReferencedFile> referencedFiles, ChutzpahTestSettingsFile chutzpahTestSettings) { var compiledMap = (from referencedFile in referencedFiles let content = fileSystem.GetText(referencedFile.Path) let jsText = GetOrAddCompiledToCache(content, referencedFile.Path) select new { FileName = referencedFile.Path, Content = jsText }) .ToDictionary(x => x.FileName, x => x.Content); return compiledMap; }
public TestHarness(ChutzpahTestSettingsFile chutzpahTestSettings, TestOptions testOptions, IEnumerable<ReferencedFile> referencedFiles, IFileSystemWrapper fileSystem) { this.chutzpahTestSettings = chutzpahTestSettings; this.testOptions = testOptions; this.referencedFiles = referencedFiles; this.fileSystem = fileSystem; BuildTags(referencedFiles); CleanupTestHarness(); }
public void Will_set_settings_file_directory() { var mockFileProbe = new Mock<IFileProbe>(); var mockSerializer = new Mock<IJsonSerializer>(); var settings = new ChutzpahTestSettingsFile(); mockFileProbe.Setup(x => x.FindTestSettingsFile(It.IsAny<string>())).Returns(@"C:\settingsDir\settingsFile.json"); mockSerializer.Setup(x => x.DeserializeFromFile<ChutzpahTestSettingsFile>(It.IsAny<string>())).Returns(settings); ChutzpahTestSettingsFile.Read("dir", mockFileProbe.Object, mockSerializer.Object); Assert.Equal(@"C:\settingsDir", settings.SettingsFileDirectory); }
public void Will_set_custom_harness_directory_based_relative_to_settings_file_directory() { var mockFileProbe = new Mock<IFileProbe>(); var mockSerializer = new Mock<IJsonSerializer>(); var settings = new ChutzpahTestSettingsFile { TestHarnessLocationMode = TestHarnessLocationMode.Custom, TestHarnessDirectory = "custom" }; mockFileProbe.Setup(x => x.FindTestSettingsFile(It.IsAny<string>())).Returns(@"C:\settingsDir2\settingsFile.json"); mockFileProbe.Setup(x => x.FindFolderPath(@"C:\settingsDir2\custom")).Returns(@"customPath"); mockSerializer.Setup(x => x.DeserializeFromFile<ChutzpahTestSettingsFile>(It.IsAny<string>())).Returns(settings); ChutzpahTestSettingsFile.Read("dir2", mockFileProbe.Object, mockSerializer.Object); Assert.Equal(@"customPath", settings.TestHarnessDirectory); }
public void Will_get_cached_settings_given_same_starting_directory() { var mockFileProbe = new Mock<IFileProbe>(); var mockSerializer = new Mock<IJsonSerializer>(); var settings = new ChutzpahTestSettingsFile(); mockFileProbe.Setup(x => x.FindTestSettingsFile("dir3")).Returns(@"C:\settingsDir3\settingsFile.json"); mockSerializer.Setup(x => x.DeserializeFromFile<ChutzpahTestSettingsFile>(It.IsAny<string>())).Returns(settings); ChutzpahTestSettingsFile.Read("dir3", mockFileProbe.Object, mockSerializer.Object); var cached = ChutzpahTestSettingsFile.Read("dir3", mockFileProbe.Object, mockSerializer.Object); Assert.Equal(@"C:\settingsDir3", cached.SettingsFileDirectory); }
/// <summary> /// Scans the test file extracting all referenced files from it. /// </summary> /// <param name="referencedFiles">The list of referenced files</param> /// <param name="definition">Test framework defintition</param> /// <param name="textToParse">The content of the file to parse and extract from</param> /// <param name="currentFilePath">Path to the file under test</param> /// <param name="chutzpahTestSettings"></param> /// <returns></returns> public void GetReferencedFiles(List<ReferencedFile> referencedFiles, IFrameworkDefinition definition, ChutzpahTestSettingsFile chutzpahTestSettings) { var filesUnderTests = referencedFiles.Where(x => x.IsFileUnderTest).ToList(); var referencePathSet = new HashSet<string>(referencedFiles.Select(x => x.Path), StringComparer.OrdinalIgnoreCase); // Process the references that the user specifies in the chutzpah settings file foreach (var reference in chutzpahTestSettings.References.Where(reference => reference != null)) { // The path we assume default to the chuzpah.json directory if the Path property is not set var referencePath = string.IsNullOrEmpty(reference.Path) ? reference.SettingsFileDirectory : reference.Path; ProcessFilePathAsReference( referencePathSet, definition, reference.SettingsFileDirectory, chutzpahTestSettings, referencePath, referencedFiles, new ReferencePathSettings(reference)); } // Process the references defined using /// <reference comments in test file contents foreach (var fileUnderTest in filesUnderTests) { var testFileText = fileSystem.GetText(fileUnderTest.Path); definition.Process(fileUnderTest, testFileText, chutzpahTestSettings); if (fileUnderTest.ExpandReferenceComments) { var result = GetReferencedFiles( referencePathSet, definition, testFileText, fileUnderTest.Path, chutzpahTestSettings); var flattenedReferenceTree = from root in result from flattened in FlattenReferenceGraph(root) select flattened; referencedFiles.AddRange(flattenedReferenceTree); } } }
/// <summary> /// This will get called for the test file and all referenced files. /// If the referenced file can be handled it generate a .js file and sets to the reference files generatedfilepath and adds the new file path to the temporary file collection /// If it can't handle the file it does nothing /// </summary> public virtual void Generate(IEnumerable<ReferencedFile> referencedFiles, IList<string> temporaryFiles, ChutzpahTestSettingsFile chutzpahTestSettings) { // Filter down to just the referenced files this generator supports referencedFiles = referencedFiles.Where(CanHandleFile).ToList(); if (referencedFiles.Any()) { var compiledMap = GenerateCompiledSources(referencedFiles, chutzpahTestSettings); foreach (var referencedFile in referencedFiles) { if (!compiledMap.ContainsKey(referencedFile.Path)) continue; var jsText = compiledMap[referencedFile.Path]; WriteGeneratedReferencedFile(referencedFile, jsText, temporaryFiles); } } }
public override IDictionary<string, string> GenerateCompiledSources(IEnumerable<ReferencedFile> referencedFiles, ChutzpahTestSettingsFile chutzpahTestSettings) { var referenceList = (from referencedFile in referencedFiles let content = fileSystem.GetText(referencedFile.Path) select new TypeScriptFile { FileName = referencedFile.Path, Content = content }).ToList(); InsertLibDeclarationFile(referenceList); var compiledMap = new Dictionary<string, string>(); var needsCompileMap = referenceList.ToDictionary(x => x.FileName, x => x.Content); if (needsCompileMap.Count > 0) { var needsCompileMapJson = jsonSerializer.Serialize(needsCompileMap); var resultJson = typeScriptEngine.Compile(needsCompileMapJson, chutzpahTestSettings.TypeScriptCodeGenTarget.ToString(), chutzpahTestSettings.TypeScriptModuleKind.ToString()); compiledMap = jsonSerializer.Deserialize<Dictionary<string, string>>(resultJson); } return compiledMap.ToDictionary(x => ToFilePath(x.Key), x => x.Value); }
public void Process(IFrameworkDefinition frameworkDefinition, ReferencedFile referencedFile, string testFileText, ChutzpahTestSettingsFile settings) { if (!referencedFile.IsFileUnderTest) { return; } var regExp = settings.TestPatternRegex ?? GetTestPattern(referencedFile, testFileText, settings); int lineNum = 1; using (var reader = new StringReader(testFileText)) { string line; while ((line = reader.ReadLine()) != null) { var match = regExp.Match(line); while (match.Success) { var testNameGroup = match.Groups["TestName"]; var testName = testNameGroup.Value; if (!string.IsNullOrWhiteSpace(testName)) { referencedFile.FilePositions.Add(lineNum, testNameGroup.Index + 1, testName); } match = match.NextMatch(); } lineNum++; } } }
/// <summary> /// Tests whether the given file is the framework itself or one of its core dependencies. /// </summary> /// <param name="referenceFileName">File name of a reference to test.</param> /// <param name="testSettingsFile"></param> /// <returns>True if the file is a framework dependency, otherwise false.</returns> public virtual bool ReferenceIsDependency(string referenceFileName, ChutzpahTestSettingsFile testSettingsFile) { string fileName = Path.GetFileName(referenceFileName); if (!string.IsNullOrEmpty(fileName)) { return GetFileDependencies(testSettingsFile).Any(x => fileName.Equals(Path.GetFileName(x), StringComparison.InvariantCultureIgnoreCase)); } return false; }
/// <summary> /// Gets the file name of the JavaScript test runner to use with the framework. /// </summary> /// <param name="chutzpahTestSettings"></param> public virtual string GetTestRunner(ChutzpahTestSettingsFile chutzpahTestSettings) { return @"JSRunners\" + FrameworkKey + "Runner.js"; }
/// <summary> /// Gets the file name of the test harness to use with the framework. /// </summary> /// <param name="chutzpahTestSettings"></param> public abstract string GetTestHarness(ChutzpahTestSettingsFile chutzpahTestSettings);
/// <summary> /// Gets a list of file dependencies to bundle with the framework test harness. /// </summary> /// <param name="chutzpahTestSettings"></param> public abstract IEnumerable<string> GetFileDependencies(ChutzpahTestSettingsFile chutzpahTestSettings);
public virtual string GetBlanketScriptName(ChutzpahTestSettingsFile chutzpahTestSettings) { return "blanket_" + FrameworkKey + ".js"; }
public virtual Dictionary<string, string> GetFrameworkReplacements(ChutzpahTestSettingsFile chutzpahTestSettings, string testFilePath, string testFileText) { return new Dictionary<string, string>(); }
/// <summary> /// Processes a referenced file according to the framework's needs. /// </summary> /// <param name="referencedFile">A referenced file to process.</param> /// <param name="testFileText"></param> /// <param name="settings"></param> public void Process(ReferencedFile referencedFile, string testFileText, ChutzpahTestSettingsFile settings) { if (FileProcessors != null) { foreach (IReferencedFileProcessor item in FileProcessors) { item.Process(this, referencedFile, testFileText, settings); } } }
/// <summary> /// Merge a selection of settings from a parent file into the current one. /// This merge will work as follows /// 1. For basic properties the child's property wins if it is different than the default /// 2. For complex objects the child's property wins if it is not null /// 3. For lists the childs items get added to the parents /// </summary> /// <param name="parent"></param> public ChutzpahTestSettingsFile InheritFrom(ChutzpahTestSettingsFile parent) { if (parent == null || this.IsDefaultSettings) { return(this); } this.References = parent.References.Concat(this.References).ToList(); this.CodeCoverageIncludes = parent.CodeCoverageIncludes.Concat(this.CodeCoverageIncludes).ToList(); this.CodeCoverageExcludes = parent.CodeCoverageExcludes.Concat(this.CodeCoverageExcludes).ToList(); this.CodeCoverageIgnores = parent.CodeCoverageIgnores.Concat(this.CodeCoverageIgnores).ToList(); this.Transforms = parent.Transforms.Concat(this.Transforms).ToList(); if (this.Compile == null) { this.Compile = parent.Compile; } this.AMDBaseUrl = this.AMDBaseUrl == null ? parent.AMDBaseUrl : this.AMDBaseUrl; this.AMDAppDirectory = this.AMDAppDirectory == null ? parent.AMDAppDirectory : this.AMDAppDirectory; this.CodeCoverageSuccessPercentage = this.CodeCoverageSuccessPercentage == null ? parent.CodeCoverageSuccessPercentage : this.CodeCoverageSuccessPercentage; this.CustomTestHarnessPath = this.CustomTestHarnessPath == null ? parent.CustomTestHarnessPath : this.CustomTestHarnessPath; this.CodeCoverageExecutionMode = this.CodeCoverageExecutionMode == null ? parent.CodeCoverageExecutionMode : this.CodeCoverageExecutionMode; this.Framework = this.Framework == null ? parent.Framework : this.Framework; this.FrameworkVersion = this.FrameworkVersion == null ? parent.FrameworkVersion : this.FrameworkVersion; this.MochaInterface = this.MochaInterface == null ? parent.MochaInterface : this.MochaInterface; this.RootReferencePathMode = this.RootReferencePathMode == null ? parent.RootReferencePathMode : this.RootReferencePathMode; this.TestFileTimeout = this.TestFileTimeout == null ? parent.TestFileTimeout : this.TestFileTimeout; this.TestHarnessReferenceMode = this.TestHarnessReferenceMode == null ? parent.TestHarnessReferenceMode : this.TestHarnessReferenceMode; this.TestPattern = this.TestPattern == null ? parent.TestPattern : this.TestPattern; this.UserAgent = this.UserAgent == null ? parent.UserAgent : this.UserAgent; this.EnableTestFileBatching = this.EnableTestFileBatching == null ? parent.EnableTestFileBatching : this.EnableTestFileBatching; this.IgnoreResourceLoadingErrors = this.IgnoreResourceLoadingErrors == null ? parent.IgnoreResourceLoadingErrors : this.IgnoreResourceLoadingErrors; // Deprecated this.AMDBasePath = this.AMDBasePath == null ? parent.AMDBasePath : this.AMDBasePath; // We need to handle an inherited test harness location mode specially // If the parent set their mode to SettingsFileAdjacent and the current file has it set to null // Then we make the curent file have a Custom mode with the parent files settings directory if (this.TestHarnessLocationMode == null) { if (parent.TestHarnessLocationMode == Chutzpah.Models.TestHarnessLocationMode.SettingsFileAdjacent && !parent.IsDefaultSettings) { this.TestHarnessLocationMode = Chutzpah.Models.TestHarnessLocationMode.Custom; this.TestHarnessDirectory = parent.SettingsFileDirectory; } else { this.TestHarnessDirectory = parent.TestHarnessDirectory; this.TestHarnessLocationMode = parent.TestHarnessLocationMode; } } return(this); }
private IList<ReferencedFile> ExpandNestedReferences( HashSet<string> discoveredPaths, IFrameworkDefinition definition, string currentFilePath, ChutzpahTestSettingsFile chutzpahTestSettings) { try { string textToParse = fileSystem.GetText(currentFilePath); return GetReferencedFiles(discoveredPaths, definition, textToParse, currentFilePath, chutzpahTestSettings); } catch (IOException e) { // Unable to get file text ChutzpahTracer.TraceError(e, "Unable to get file text from test reference with path {0}", currentFilePath); } return new List<ReferencedFile>(); }
private ReferencedFile VisitReferencedFile( string absoluteFilePath, IFrameworkDefinition definition, HashSet<string> discoveredPaths, ICollection<ReferencedFile> referencedFiles, ChutzpahTestSettingsFile chutzpahTestSettings, ReferencePathSettings pathSettings) { // If the file doesn't exit exist or we have seen it already then return if (discoveredPaths.Contains(absoluteFilePath)) return null; var referencedFile = new ReferencedFile { Path = absoluteFilePath, IsLocal = true, IsTestFrameworkFile = pathSettings.IsTestFrameworkFile, IncludeInTestHarness = pathSettings.IncludeInTestHarness || chutzpahTestSettings.TestHarnessReferenceMode == TestHarnessReferenceMode.Normal, TemplateOptions = pathSettings.TemplateOptions }; ChutzpahTracer.TraceInformation( "Added file '{0}' to referenced files. Local: {1}, IncludeInTestHarness: {2}", referencedFile.Path, referencedFile.IsLocal, referencedFile.IncludeInTestHarness); referencedFiles.Add(referencedFile); discoveredPaths.Add(referencedFile.Path); // Remmember this path to detect reference loops ChutzpahTracer.TraceInformation("Processing referenced file '{0}' for expanded references", absoluteFilePath); if (pathSettings.ExpandReferenceComments) { referencedFile.ReferencedFiles = ExpandNestedReferences(discoveredPaths, definition, absoluteFilePath, chutzpahTestSettings); } return referencedFile; }
/// <summary> /// If the reference path is rooted (e.g. /some/path) and the user chose to adjust it then change it /// </summary> /// <returns></returns> private static string AdjustPathIfRooted(ChutzpahTestSettingsFile chutzpahTestSettings, string referencePath) { if (chutzpahTestSettings.RootReferencePathMode == RootReferencePathMode.SettingsFileDirectory && (referencePath.StartsWith("/") || referencePath.StartsWith("\\"))) { ChutzpahTracer.TraceInformation( "Changing reference '{0}' to be rooted from settings directory '{1}'", referencePath, chutzpahTestSettings.SettingsFileDirectory); referencePath = chutzpahTestSettings.SettingsFileDirectory + referencePath; } return referencePath; }
private void ProcessFilePathAsReference( HashSet<string> discoveredPaths, IFrameworkDefinition definition, string relativeProcessingPath, ChutzpahTestSettingsFile chutzpahTestSettings, string referencePath, List<ReferencedFile> referencedFiles, ReferencePathSettings pathSettings) { ChutzpahTracer.TraceInformation("Investigating reference file path '{0}'", referencePath); // Check test settings and adjust the path if it is rooted (e.g. /some/path) referencePath = AdjustPathIfRooted(chutzpahTestSettings, referencePath); var referenceUri = new Uri(referencePath, UriKind.RelativeOrAbsolute); string referenceFileName = Path.GetFileName(referencePath); // Ignore test runner, since we use our own. if (definition.ReferenceIsDependency(referenceFileName, chutzpahTestSettings)) { ChutzpahTracer.TraceInformation( "Ignoring reference file '{0}' as a duplicate reference to {1}", referenceFileName, definition.FrameworkKey); return; } var isRelativeUri = !referenceUri.IsAbsoluteUri; // If this either a relative uri or a file uri if (isRelativeUri || referenceUri.IsFile) { var relativeProcessingPathFolder = fileSystem.FolderExists(relativeProcessingPath) ? relativeProcessingPath : Path.GetDirectoryName(relativeProcessingPath); string relativeReferencePath = Path.Combine(relativeProcessingPathFolder, referencePath); // Check if reference is a file string absoluteFilePath = fileProbe.FindFilePath(relativeReferencePath); if (absoluteFilePath != null) { VisitReferencedFile(absoluteFilePath, definition, discoveredPaths, referencedFiles, chutzpahTestSettings, pathSettings); return; } // Check if reference is a folder string absoluteFolderPath = fileProbe.FindFolderPath(relativeReferencePath); if (absoluteFolderPath != null) { var includePatterns = pathSettings.Includes.Select(x => FileProbe.NormalizeFilePath(x)).ToList(); var excludePatterns = pathSettings.Excludes.Select(x => FileProbe.NormalizeFilePath(x)).ToList(); // Find all files in this folder including sub-folders. This can be ALOT of files. // Only a subset of these files Chutzpah might understand so many of these will be ignored. var childFiles = fileSystem.GetFiles(absoluteFolderPath, "*.*", SearchOption.AllDirectories); var validFiles = from file in childFiles let normalizedFile = FileProbe.NormalizeFilePath(file) where !fileProbe.IsTemporaryChutzpahFile(file) && (!includePatterns.Any() || includePatterns.Any(pat => NativeImports.PathMatchSpec(normalizedFile, pat))) && (!excludePatterns.Any() || !excludePatterns.Any(pat => NativeImports.PathMatchSpec(normalizedFile, pat))) select file; validFiles.ForEach(file => VisitReferencedFile(file, definition, discoveredPaths, referencedFiles, chutzpahTestSettings, pathSettings)); return; } // At this point we know that this file/folder does not exist! ChutzpahTracer.TraceWarning("Referenced file '{0}' which was resolved to '{1}' does not exist", referencePath, relativeReferencePath); } else if (referenceUri.IsAbsoluteUri) { var referencedFile = new ReferencedFile { Path = referencePath, IsLocal = false, IncludeInTestHarness = true, IsTestFrameworkFile = pathSettings.IsTestFrameworkFile, TemplateOptions = pathSettings.TemplateOptions }; ChutzpahTracer.TraceInformation( "Added file '{0}' to referenced files. Local: {1}, IncludeInTestHarness: {2}", referencedFile.Path, referencedFile.IsLocal, referencedFile.IncludeInTestHarness); referencedFiles.Add(referencedFile); } }
private IList<ReferencedFile> GetReferencedFiles( HashSet<string> discoveredPaths, IFrameworkDefinition definition, string textToParse, string currentFilePath, ChutzpahTestSettingsFile chutzpahTestSettings) { var referencedFiles = new List<ReferencedFile>(); Regex regex = RegexPatterns.JsReferencePathRegex; foreach (Match match in regex.Matches(textToParse)) { if (!ShouldIncludeReference(match)) continue; string referencePath = match.Groups["Path"].Value; ProcessFilePathAsReference( discoveredPaths, definition, currentFilePath, chutzpahTestSettings, referencePath, referencedFiles, new ReferencePathSettings()); } foreach (Match match in RegexPatterns.JsTemplatePathRegex.Matches(textToParse)) { string referencePath = null, templateId = null, templateType = null; TemplateMode templateMode = TemplateMode.Raw; for (var i = 0; i < match.Groups["PropName"].Captures.Count; i++) { var propName = match.Groups["PropName"].Captures[i].Value.ToLowerInvariant(); var propValue = match.Groups["PropValue"].Captures[i].Value; switch (propName) { case "path": referencePath = propValue; break; case "id": templateId = propValue; break; case "type": templateType = propValue; break; case "mode": if(propValue.Equals("script", StringComparison.OrdinalIgnoreCase)) { templateMode = TemplateMode.Script; } break; default: break; } } referencePath = AdjustPathIfRooted(chutzpahTestSettings, referencePath); string relativeReferencePath = Path.Combine(Path.GetDirectoryName(currentFilePath), referencePath); string absoluteFilePath = fileProbe.FindFilePath(relativeReferencePath); if (referencedFiles.All(r => r.Path != absoluteFilePath)) { ChutzpahTracer.TraceInformation("Added html template '{0}' to referenced files", absoluteFilePath); referencedFiles.Add(new ReferencedFile { Path = absoluteFilePath, IsLocal = false, IncludeInTestHarness = true, TemplateOptions = new TemplateOptions { Mode = templateMode, Id = templateId, Type = templateType } }); } } return referencedFiles; }
/// <summary> /// Add the AMD file paths for the Path and GeneratePath fields /// </summary> /// <param name="referencedFiles"></param> /// <param name="testHarnessDirectory"></param> /// <param name="testSettings"></param> private void SetupLegacyAmdFilePaths(List<ReferencedFile> referencedFiles, string testHarnessDirectory, ChutzpahTestSettingsFile testSettings) { // If the user set a AMD base path then we must relativize the amd path's using the path from the base path to the test harness directory string relativeAmdRootPath = ""; if (!string.IsNullOrEmpty(testSettings.AMDBasePath)) { relativeAmdRootPath = FileProbe.GetRelativePath(testSettings.AMDBasePath, testHarnessDirectory); } foreach (var referencedFile in referencedFiles) { referencedFile.AmdFilePath = GetLegacyAmdPath(testHarnessDirectory, referencedFile.Path, relativeAmdRootPath); if (!string.IsNullOrEmpty(referencedFile.GeneratedFilePath)) { referencedFile.AmdGeneratedFilePath = GetLegacyAmdPath(testHarnessDirectory, referencedFile.GeneratedFilePath, relativeAmdRootPath); } } }
/// <summary> /// Merge a selection of settings from a parent file into the current one. /// This merge will work as follows /// 1. For basic properties the child's property wins if it is different than the default /// 2. For complex objects the child's property wins if it is not null /// 3. For lists the childs items get added to the parents /// </summary> /// <param name="parent"></param> public ChutzpahTestSettingsFile InheritFrom(ChutzpahTestSettingsFile parent) { if (parent == null || this.IsDefaultSettings) { return(this); } this.References = parent.References.Concat(this.References).ToList(); this.CodeCoverageIncludes = parent.CodeCoverageIncludes.Concat(this.CodeCoverageIncludes).ToList(); this.CodeCoverageExcludes = parent.CodeCoverageExcludes.Concat(this.CodeCoverageExcludes).ToList(); this.CodeCoverageIgnores = parent.CodeCoverageIgnores.Concat(this.CodeCoverageIgnores).ToList(); this.Transforms = parent.Transforms.Concat(this.Transforms).ToList(); foreach (var browserArgument in parent.BrowserArguments) { // We should only override the child if the child does not already define a value for a key if (this.BrowserArguments.ContainsKey(browserArgument.Key)) { continue; } this.BrowserArguments[browserArgument.Key] = browserArgument.Value; } if (this.Server == null) { this.Server = parent.Server; } else if (this.Server != null && parent.Server != null // Only allow override if the parent is a force configuration which is used for testing && !(parent.Server is ForcedChutzpahWebServerConfiguration) ) { ChutzpahTracer.TraceWarning("Ignoring Server setting in child settings file since it is already configured in parent"); this.Server = new ChutzpahWebServerConfiguration(parent.Server); } if (this.Compile == null) { this.Compile = parent.Compile; } else if (this.Compile != null && parent.Compile != null) { this.Compile.Arguments = this.Compile.Arguments ?? parent.Compile.Arguments; this.Compile.Executable = this.Compile.Executable ?? parent.Compile.Executable; this.Compile.Extensions = this.Compile.Extensions.Any() ? this.Compile.Extensions : parent.Compile.Extensions; this.Compile.ExtensionsWithNoOutput = this.Compile.ExtensionsWithNoOutput.Any() ? this.Compile.ExtensionsWithNoOutput : parent.Compile.ExtensionsWithNoOutput; this.Compile.Mode = this.Compile.Mode ?? parent.Compile.Mode; this.Compile.IgnoreMissingFiles = this.Compile.IgnoreMissingFiles ?? parent.Compile.IgnoreMissingFiles; this.Compile.UseSourceMaps = this.Compile.UseSourceMaps ?? parent.Compile.UseSourceMaps; this.Compile.SkipIfUnchanged = this.Compile.SkipIfUnchanged ?? parent.Compile.SkipIfUnchanged; this.Compile.WorkingDirectory = this.Compile.WorkingDirectory ?? parent.Compile.WorkingDirectory; this.Compile.Timeout = this.Compile.Timeout ?? parent.Compile.Timeout; this.Compile.Paths = this.Compile.Paths.Concat(parent.Compile.Paths).ToList(); } this.AMDBaseUrl = this.AMDBaseUrl ?? parent.AMDBaseUrl; this.AMDAppDirectory = this.AMDAppDirectory ?? parent.AMDAppDirectory; this.CodeCoverageSuccessPercentage = this.CodeCoverageSuccessPercentage ?? parent.CodeCoverageSuccessPercentage; this.CustomTestHarnessPath = this.CustomTestHarnessPath ?? parent.CustomTestHarnessPath; this.CodeCoverageExecutionMode = this.CodeCoverageExecutionMode ?? parent.CodeCoverageExecutionMode; this.Framework = this.Framework ?? parent.Framework; this.FrameworkVersion = this.FrameworkVersion ?? parent.FrameworkVersion; this.MochaInterface = this.MochaInterface ?? parent.MochaInterface; this.RootReferencePathMode = this.RootReferencePathMode ?? parent.RootReferencePathMode; this.TestFileTimeout = this.TestFileTimeout ?? parent.TestFileTimeout; this.TestHarnessReferenceMode = this.TestHarnessReferenceMode ?? parent.TestHarnessReferenceMode; this.TestPattern = this.TestPattern ?? parent.TestPattern; this.UserAgent = this.UserAgent ?? parent.UserAgent; this.EnableTestFileBatching = this.EnableTestFileBatching ?? parent.EnableTestFileBatching; this.IgnoreResourceLoadingErrors = this.IgnoreResourceLoadingErrors ?? parent.IgnoreResourceLoadingErrors; this.Parallelism = this.Parallelism ?? parent.Parallelism; this.EnableTracing = this.EnableTracing ?? parent.EnableTracing; this.TraceFilePath = this.TraceFilePath ?? parent.TraceFilePath; this.CodeCoverageTimeout = this.CodeCoverageTimeout ?? parent.CodeCoverageTimeout; this.Proxy = this.Proxy ?? parent.Proxy; this.CreateFailedTestForFileError = this.CreateFailedTestForFileError ?? parent.CreateFailedTestForFileError; // Deprecated this.AMDBasePath = this.AMDBasePath ?? parent.AMDBasePath; // We need to handle an inherited test harness location mode specially // If the parent set their mode to SettingsFileAdjacent and the current file has it set to null // Then we make the current file have a Custom mode with the parent files settings directory if (this.TestHarnessLocationMode == null) { if (parent.TestHarnessLocationMode == Chutzpah.Models.TestHarnessLocationMode.SettingsFileAdjacent && !parent.IsDefaultSettings) { this.TestHarnessLocationMode = Chutzpah.Models.TestHarnessLocationMode.Custom; this.TestHarnessDirectory = parent.SettingsFileDirectory; } else { this.TestHarnessDirectory = parent.TestHarnessDirectory; this.TestHarnessLocationMode = parent.TestHarnessLocationMode; } } return(this); }
public IEnumerable<PathInfo> FindScriptFiles(ChutzpahTestSettingsFile chutzpahTestSettings) { if (chutzpahTestSettings == null) yield break; foreach (var pathSettings in chutzpahTestSettings.Tests.Where(x => x != null)) { var includePatterns = pathSettings.Includes.Select(x => NormalizeFilePath(x)).ToList(); var excludePatterns = pathSettings.Excludes.Select(x => NormalizeFilePath(x)).ToList(); // The path we assume default to the chuzpah.json directory if the Path property is not set var testPath = string.IsNullOrEmpty(pathSettings.Path) ? pathSettings.SettingsFileDirectory : pathSettings.Path; testPath = NormalizeFilePath(testPath); testPath = testPath != null ? Path.Combine(pathSettings.SettingsFileDirectory, testPath) : null; // If a file path is given just return that file var filePath = FindFilePath(testPath); if (filePath != null) { ChutzpahTracer.TraceInformation("Found file {0} from chutzpah.json", filePath); yield return GetPathInfo(filePath); } // If a folder path is given enumerate that folder (recursively) with the optional include/exclude paths var folderPath = NormalizeFilePath(FindFolderPath(testPath)); if (folderPath != null) { var childFiles = fileSystem.GetFiles(folderPath, "*.*", SearchOption.AllDirectories); var validFiles = from file in childFiles let normalizedFile = NormalizeFilePath(file) where !IsTemporaryChutzpahFile(normalizedFile) && (!includePatterns.Any() || includePatterns.Any(pat => NativeImports.PathMatchSpec(normalizedFile, pat))) && (!excludePatterns.Any() || !excludePatterns.Any(pat => NativeImports.PathMatchSpec(normalizedFile, pat))) select file; foreach (var item in validFiles) { yield return GetPathInfo(item); } } } }
public TestContext() { ReferencedFiles = new List <ReferencedFile>(); TemporaryFiles = new List <string>(); TestFileSettings = new ChutzpahTestSettingsFile().InheritFromDefault(); }