Merge pull request #326 from microsoft/prupipho-169-IncreaseCodeCoverage
Increase code coverage:
This commit is contained in:
Коммит
fc2bc80ba7
|
@ -12,7 +12,7 @@ namespace Microsoft.Templates.Core
|
||||||
{
|
{
|
||||||
public static int SafeIndexOf(this IEnumerable<string> source, string item, int skip, bool ignoreWhiteLines = true, bool compareUpToItemLength = false)
|
public static int SafeIndexOf(this IEnumerable<string> source, string item, int skip, bool ignoreWhiteLines = true, bool compareUpToItemLength = false)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(item) && ignoreWhiteLines)
|
if (source == null || (string.IsNullOrWhiteSpace(item) && ignoreWhiteLines))
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,49 +3,30 @@
|
||||||
// See the LICENSE file in the project root for more information.
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using Microsoft.Templates.Core.Resources;
|
||||||
|
|
||||||
namespace Microsoft.Templates.Core
|
namespace Microsoft.Templates.Core
|
||||||
{
|
{
|
||||||
public static class StringExtensions
|
public static class StringExtensions
|
||||||
{
|
{
|
||||||
public static string ObfuscateSHA(this string data)
|
|
||||||
{
|
|
||||||
string result = data;
|
|
||||||
byte[] b64data = Encoding.UTF8.GetBytes(data);
|
|
||||||
|
|
||||||
using (SHA512 sha2 = SHA512.Create())
|
|
||||||
{
|
|
||||||
result = GetHash(sha2, b64data);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result.ToUpperInvariant();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string GetHash(HashAlgorithm md5Hash, byte[] inputData)
|
|
||||||
{
|
|
||||||
byte[] data = md5Hash.ComputeHash(inputData);
|
|
||||||
|
|
||||||
var sb = new StringBuilder();
|
|
||||||
|
|
||||||
for (int i = 0; i < data.Length; i++)
|
|
||||||
{
|
|
||||||
sb.Append(data[i].ToString("x2"));
|
|
||||||
}
|
|
||||||
|
|
||||||
return sb.ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string[] GetMultiValue(this string value)
|
public static string[] GetMultiValue(this string value)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(value))
|
if (string.IsNullOrWhiteSpace(value) || string.IsNullOrEmpty(value.Trim()))
|
||||||
{
|
{
|
||||||
return new string[0];
|
return new string[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
return value.Split("|".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
|
var values = value.Split("|".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
if (values.Any(v => v != v.Trim()))
|
||||||
|
{
|
||||||
|
throw new InvalidDataException(string.Format(StringRes.ErrorExtraWhitespacesInMultiValues, value));
|
||||||
|
}
|
||||||
|
|
||||||
|
return values;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool IsMultiValue(this string value)
|
public static bool IsMultiValue(this string value)
|
||||||
|
|
|
@ -10,17 +10,12 @@ namespace Microsoft.Templates.Core
|
||||||
{
|
{
|
||||||
public static bool IsZero(this Version v)
|
public static bool IsZero(this Version v)
|
||||||
{
|
{
|
||||||
return !v.IsNull() && (v.Major + v.Minor + v.Build + v.Revision) == 0;
|
return !v.IsNull() && v.Major <= 0 && v.Minor <= 0 && v.Build <= 0 && v.Revision <= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool IsNull(this Version v)
|
public static bool IsNull(this Version v)
|
||||||
{
|
{
|
||||||
return v is null;
|
return v is null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool IsNullOrZero(this Version v)
|
|
||||||
{
|
|
||||||
return v.IsNull() || (v.Major + v.Minor + v.Build + v.Revision) == 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,49 +0,0 @@
|
||||||
// Licensed to the .NET Foundation under one or more agreements.
|
|
||||||
// The .NET Foundation licenses this file to you under the MIT license.
|
|
||||||
// See the LICENSE file in the project root for more information.
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Xml.Linq;
|
|
||||||
|
|
||||||
namespace Microsoft.Templates.Core
|
|
||||||
{
|
|
||||||
public static class XElementExtensions
|
|
||||||
{
|
|
||||||
public static XElement Select(this XElement xelement, string path)
|
|
||||||
{
|
|
||||||
var pathChunks = path.Split("/".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
|
|
||||||
|
|
||||||
if (pathChunks.Length <= 1)
|
|
||||||
{
|
|
||||||
return xelement;
|
|
||||||
}
|
|
||||||
|
|
||||||
var result = xelement;
|
|
||||||
|
|
||||||
for (int i = 1; i < pathChunks.Length; i++)
|
|
||||||
{
|
|
||||||
var chunk = pathChunks[i];
|
|
||||||
result = result.Element(xelement.GetDefaultNamespace() + chunk);
|
|
||||||
|
|
||||||
if (result == null)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void CopyNamespaces(this XElement xelement, XElement source)
|
|
||||||
{
|
|
||||||
foreach (var ns in source.Attributes().Where(a => a.IsNamespaceDeclaration).ToList())
|
|
||||||
{
|
|
||||||
if (!xelement.Attributes().Any(a => a.IsNamespaceDeclaration && a.Name.LocalName == ns.Name.LocalName))
|
|
||||||
{
|
|
||||||
xelement.Add(ns);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -108,7 +108,7 @@ namespace Microsoft.Templates.Core.Gen
|
||||||
string projectGuid = ToolBox.Shell.Project.GetProjectGuidByName(GenContext.Current.ProjectName).ToString();
|
string projectGuid = ToolBox.Shell.Project.GetProjectGuidByName(GenContext.Current.ProjectName).ToString();
|
||||||
var projectTempFolder = Path.Combine(_tempGenerationFolder, projectGuid);
|
var projectTempFolder = Path.Combine(_tempGenerationFolder, projectGuid);
|
||||||
|
|
||||||
Fs.EnsureFolder(projectTempFolder);
|
Fs.EnsureFolderExists(projectTempFolder);
|
||||||
var tempGenerationName = $"{projectName}_{DateTime.Now.FormatAsShortDateTime()}";
|
var tempGenerationName = $"{projectName}_{DateTime.Now.FormatAsShortDateTime()}";
|
||||||
var inferredName = NamingService.Infer(tempGenerationName, new List<Validator> { new FolderNameValidator(projectTempFolder) }, "_");
|
var inferredName = NamingService.Infer(tempGenerationName, new List<Validator> { new FolderNameValidator(projectTempFolder) }, "_");
|
||||||
|
|
||||||
|
|
|
@ -4,10 +4,8 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
using Microsoft.Templates.Core.Diagnostics;
|
using Microsoft.Templates.Core.Diagnostics;
|
||||||
using Microsoft.Templates.Core.Resources;
|
using Microsoft.Templates.Core.Resources;
|
||||||
|
@ -16,11 +14,19 @@ namespace Microsoft.Templates.Core.Helpers
|
||||||
{
|
{
|
||||||
public static class Fs
|
public static class Fs
|
||||||
{
|
{
|
||||||
public static void EnsureFolder(string folder)
|
public static void EnsureFolderExists(string folder)
|
||||||
{
|
{
|
||||||
if (!Directory.Exists(folder))
|
try
|
||||||
{
|
{
|
||||||
Directory.CreateDirectory(folder);
|
if (!Directory.Exists(folder))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(folder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
var message = string.Format(StringRes.ErrorCreatingFolder, folder, ex.Message);
|
||||||
|
AppHealth.Current.Warning.TrackAsync(message, ex).FireAndForget();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,42 +45,11 @@ namespace Microsoft.Templates.Core.Helpers
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task<int> CopyRecursiveAsync(string sourceDir, string targetDir, int totalNumber, int counter, int latestProgress, bool overwrite = false, Action<int> reportProgress = null)
|
|
||||||
{
|
|
||||||
Directory.CreateDirectory(targetDir);
|
|
||||||
|
|
||||||
foreach (var file in Directory.GetFiles(sourceDir))
|
|
||||||
{
|
|
||||||
counter++;
|
|
||||||
var progress = Convert.ToInt32((counter * 100) / totalNumber);
|
|
||||||
if (progress != latestProgress)
|
|
||||||
{
|
|
||||||
reportProgress?.Invoke(progress);
|
|
||||||
latestProgress = progress;
|
|
||||||
}
|
|
||||||
|
|
||||||
await Task.Run(() =>
|
|
||||||
{
|
|
||||||
File.Copy(file, Path.Combine(targetDir, Path.GetFileName(file)), overwrite);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var directory in Directory.GetDirectories(sourceDir))
|
|
||||||
{
|
|
||||||
counter = await CopyRecursiveAsync(directory, Path.Combine(targetDir, Path.GetFileName(directory)), totalNumber, counter, latestProgress, overwrite, reportProgress);
|
|
||||||
}
|
|
||||||
|
|
||||||
return counter;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void SafeCopyFile(string sourceFile, string destFolder, bool overwrite)
|
public static void SafeCopyFile(string sourceFile, string destFolder, bool overwrite)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (!Directory.Exists(destFolder))
|
EnsureFolderExists(destFolder);
|
||||||
{
|
|
||||||
Directory.CreateDirectory(destFolder);
|
|
||||||
}
|
|
||||||
|
|
||||||
var destFile = Path.Combine(destFolder, Path.GetFileName(sourceFile));
|
var destFile = Path.Combine(destFolder, Path.GetFileName(sourceFile));
|
||||||
|
|
||||||
|
@ -131,23 +106,6 @@ namespace Microsoft.Templates.Core.Helpers
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task SafeMoveDirectoryAsync(string sourceDir, string targetDir, bool overwrite = false, Action<int> reportProgress = null)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (Directory.Exists(sourceDir))
|
|
||||||
{
|
|
||||||
var totalFiles = Directory.GetFiles(sourceDir, "*.*", SearchOption.AllDirectories).Length;
|
|
||||||
await CopyRecursiveAsync(sourceDir, targetDir, totalFiles, 0, 0, overwrite, reportProgress);
|
|
||||||
SafeDeleteDirectory(sourceDir);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
AppHealth.Current.Warning.TrackAsync(string.Format(StringRes.FsSafeMoveDirectoryMessage, sourceDir, targetDir, ex.Message), ex).FireAndForget();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void EnsureFileEditable(string filePath)
|
public static void EnsureFileEditable(string filePath)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@ -160,8 +118,8 @@ namespace Microsoft.Templates.Core.Helpers
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
var msg = string.Format(StringRes.FsEnsureFileEditableException, filePath);
|
var message = string.Format(StringRes.FsEnsureFileEditableException, filePath);
|
||||||
AppHealth.Current.Warning.TrackAsync(msg, ex).FireAndForget();
|
AppHealth.Current.Warning.TrackAsync(message, ex).FireAndForget();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -75,7 +75,7 @@ namespace Microsoft.Templates.Core.Locations
|
||||||
var tempFolder = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
|
var tempFolder = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
|
||||||
var sourceUrl = $"{_cdnUrl}/{packageInfo.Name}";
|
var sourceUrl = $"{_cdnUrl}/{packageInfo.Name}";
|
||||||
var fileTarget = Path.Combine(tempFolder, packageInfo.Name);
|
var fileTarget = Path.Combine(tempFolder, packageInfo.Name);
|
||||||
Fs.EnsureFolder(tempFolder);
|
Fs.EnsureFolderExists(tempFolder);
|
||||||
|
|
||||||
await DownloadContentAsync(sourceUrl, fileTarget, ct);
|
await DownloadContentAsync(sourceUrl, fileTarget, ct);
|
||||||
packageInfo.LocalPath = fileTarget;
|
packageInfo.LocalPath = fileTarget;
|
||||||
|
@ -87,7 +87,7 @@ namespace Microsoft.Templates.Core.Locations
|
||||||
var tempFolder = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
|
var tempFolder = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
|
||||||
var sourceUrl = $"{_cdnUrl}/config.json";
|
var sourceUrl = $"{_cdnUrl}/config.json";
|
||||||
var fileTarget = Path.Combine(tempFolder, "config.json");
|
var fileTarget = Path.Combine(tempFolder, "config.json");
|
||||||
Fs.EnsureFolder(tempFolder);
|
Fs.EnsureFolderExists(tempFolder);
|
||||||
|
|
||||||
await DownloadContentAsync(sourceUrl, fileTarget, ct);
|
await DownloadContentAsync(sourceUrl, fileTarget, ct);
|
||||||
|
|
||||||
|
|
|
@ -336,7 +336,7 @@ namespace Microsoft.Templates.Core.Locations
|
||||||
fileInfo.Delete();
|
fileInfo.Delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
Fs.EnsureFolder(_content.TemplatesFolder);
|
Fs.EnsureFolderExists(_content.TemplatesFolder);
|
||||||
File.WriteAllText(fileInfo.FullName, "Instance syncing");
|
File.WriteAllText(fileInfo.FullName, "Instance syncing");
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
|
|
@ -11,6 +11,7 @@ using System.Net.Mime;
|
||||||
using System.Security;
|
using System.Security;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
using System.Security.Cryptography.X509Certificates;
|
using System.Security.Cryptography.X509Certificates;
|
||||||
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
@ -262,7 +263,7 @@ namespace Microsoft.Templates.Core.Packaging
|
||||||
var certInfo = new CertInfo()
|
var certInfo = new CertInfo()
|
||||||
{
|
{
|
||||||
Cert = new X509Certificate2(cert),
|
Cert = new X509Certificate2(cert),
|
||||||
Pin = cert.GetPublicKeyString().ObfuscateSHA(),
|
Pin = Obfuscate(cert.GetPublicKeyString()),
|
||||||
Status = _digitalSignatureService.VerifyCertificate(cert),
|
Status = _digitalSignatureService.VerifyCertificate(cert),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -340,11 +341,43 @@ namespace Microsoft.Templates.Core.Packaging
|
||||||
return status == X509ChainStatusFlags.NoError;
|
return status == X509ChainStatusFlags.NoError;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static string GetHash(HashAlgorithm md5Hash, byte[] inputData)
|
||||||
|
{
|
||||||
|
byte[] data = md5Hash.ComputeHash(inputData);
|
||||||
|
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
|
||||||
|
for (int i = 0; i < data.Length; i++)
|
||||||
|
{
|
||||||
|
sb.Append(data[i].ToString("x2"));
|
||||||
|
}
|
||||||
|
|
||||||
|
return sb.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string Obfuscate(string data)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(data))
|
||||||
|
{
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
string result = data;
|
||||||
|
byte[] b64data = Encoding.UTF8.GetBytes(data);
|
||||||
|
|
||||||
|
using (SHA512 sha2 = SHA512.Create())
|
||||||
|
{
|
||||||
|
result = GetHash(sha2, b64data);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.ToUpperInvariant();
|
||||||
|
}
|
||||||
|
|
||||||
private bool VerifyAllowedPublicKey(X509Certificate cert)
|
private bool VerifyAllowedPublicKey(X509Certificate cert)
|
||||||
{
|
{
|
||||||
var pubKeyCert = cert.GetPublicKeyString();
|
var pubKeyCert = cert.GetPublicKeyString();
|
||||||
|
|
||||||
var pubKeyPin = pubKeyCert.ObfuscateSHA();
|
var pubKeyPin = Obfuscate(pubKeyCert);
|
||||||
|
|
||||||
AppHealth.Current.Verbose.TrackAsync($"{StringRes.PackageCertificateString} {cert.Subject}").FireAndForget();
|
AppHealth.Current.Verbose.TrackAsync($"{StringRes.PackageCertificateString} {cert.Subject}").FireAndForget();
|
||||||
AppHealth.Current.Verbose.TrackAsync($"Key: {pubKeyCert}").FireAndForget();
|
AppHealth.Current.Verbose.TrackAsync($"Key: {pubKeyCert}").FireAndForget();
|
||||||
|
|
|
@ -114,6 +114,15 @@ namespace Microsoft.Templates.Core.Resources {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to Error creating folder '{0}': {1}.
|
||||||
|
/// </summary>
|
||||||
|
public static string ErrorCreatingFolder {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("ErrorCreatingFolder", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to Circular dependency detected on template {0} with {1}..
|
/// Looks up a localized string similar to Circular dependency detected on template {0} with {1}..
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -213,6 +222,15 @@ namespace Microsoft.Templates.Core.Resources {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to Multivalue field: '{0}' contains trailing or leading whitespaces..
|
||||||
|
/// </summary>
|
||||||
|
public static string ErrorExtraWhitespacesInMultiValues {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("ErrorExtraWhitespacesInMultiValues", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to Template '{0}', name: '{1}', reason: '{2}'.
|
/// Looks up a localized string similar to Template '{0}', name: '{1}', reason: '{2}'.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -457,7 +475,7 @@ namespace Microsoft.Templates.Core.Resources {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to The folder {0} can't be delete. Error: {1}.
|
/// Looks up a localized string similar to The folder {0} can't be deleted. Error: {1}.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string FsSafeDeleteDirectoryMessage {
|
public static string FsSafeDeleteDirectoryMessage {
|
||||||
get {
|
get {
|
||||||
|
@ -466,7 +484,7 @@ namespace Microsoft.Templates.Core.Resources {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to The file {0} can't be delete. Error: {1}.
|
/// Looks up a localized string similar to The file {0} can't be deleted. Error: {1}.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string FsSafeDeleteFileMessage {
|
public static string FsSafeDeleteFileMessage {
|
||||||
get {
|
get {
|
||||||
|
@ -493,7 +511,7 @@ namespace Microsoft.Templates.Core.Resources {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to The folder {0} can't be rename. Error: {1}.
|
/// Looks up a localized string similar to The folder {0} can't be renamed. Error: {1}.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string FsSafeRenameDirectoryMessage {
|
public static string FsSafeRenameDirectoryMessage {
|
||||||
get {
|
get {
|
||||||
|
|
|
@ -581,4 +581,12 @@ Nemohly být integrovány následující změny: {2}
|
||||||
<data name="TemplatesSynchronizationError" xml:space="preserve">
|
<data name="TemplatesSynchronizationError" xml:space="preserve">
|
||||||
<value>Error synchronizing templates.</value>
|
<value>Error synchronizing templates.</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="ErrorCreatingFolder" xml:space="preserve">
|
||||||
|
<value>Error creating folder '{0}': {1}</value>
|
||||||
|
<comment>{0} Name of the folder, {1} exception message</comment>
|
||||||
|
</data>
|
||||||
|
<data name="ErrorExtraWhitespacesInMultiValues" xml:space="preserve">
|
||||||
|
<value>Multivalue field: '{0}' contains trailing or leading whitespaces.</value>
|
||||||
|
<comment>{0}: multivalue string</comment>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
|
@ -581,4 +581,12 @@ Die folgenden Änderungen konnten nicht integriert werden: {2}
|
||||||
<data name="TemplatesSynchronizationError" xml:space="preserve">
|
<data name="TemplatesSynchronizationError" xml:space="preserve">
|
||||||
<value>Error synchronizing templates.</value>
|
<value>Error synchronizing templates.</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="ErrorCreatingFolder" xml:space="preserve">
|
||||||
|
<value>Error creating folder '{0}': {1}</value>
|
||||||
|
<comment>{0} Name of the folder, {1} exception message</comment>
|
||||||
|
</data>
|
||||||
|
<data name="ErrorExtraWhitespacesInMultiValues" xml:space="preserve">
|
||||||
|
<value>Multivalue field: '{0}' contains trailing or leading whitespaces.</value>
|
||||||
|
<comment>{0}: multivalue string</comment>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
|
@ -581,4 +581,12 @@ No se pueden integrar las modificaciones siguientes: {2}
|
||||||
<data name="TemplatesSynchronizationError" xml:space="preserve">
|
<data name="TemplatesSynchronizationError" xml:space="preserve">
|
||||||
<value>Error synchronizing templates.</value>
|
<value>Error synchronizing templates.</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="ErrorCreatingFolder" xml:space="preserve">
|
||||||
|
<value>Error creating folder '{0}': {1}</value>
|
||||||
|
<comment>{0} Name of the folder, {1} exception message</comment>
|
||||||
|
</data>
|
||||||
|
<data name="ErrorExtraWhitespacesInMultiValues" xml:space="preserve">
|
||||||
|
<value>Multivalue field: '{0}' contains trailing or leading whitespaces.</value>
|
||||||
|
<comment>{0}: multivalue string</comment>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
|
@ -581,4 +581,12 @@ Les modifications suivantes n'ont pu être intégrées : {2}
|
||||||
<data name="TemplatesSynchronizationError" xml:space="preserve">
|
<data name="TemplatesSynchronizationError" xml:space="preserve">
|
||||||
<value>Error synchronizing templates.</value>
|
<value>Error synchronizing templates.</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="ErrorCreatingFolder" xml:space="preserve">
|
||||||
|
<value>Error creating folder '{0}': {1}</value>
|
||||||
|
<comment>{0} Name of the folder, {1} exception message</comment>
|
||||||
|
</data>
|
||||||
|
<data name="ErrorExtraWhitespacesInMultiValues" xml:space="preserve">
|
||||||
|
<value>Multivalue field: '{0}' contains trailing or leading whitespaces.</value>
|
||||||
|
<comment>{0}: multivalue string</comment>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
|
@ -581,4 +581,12 @@ Impossibile integrare le seguenti modifiche: {2}
|
||||||
<data name="TemplatesSynchronizationError" xml:space="preserve">
|
<data name="TemplatesSynchronizationError" xml:space="preserve">
|
||||||
<value>Error synchronizing templates.</value>
|
<value>Error synchronizing templates.</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="ErrorCreatingFolder" xml:space="preserve">
|
||||||
|
<value>Error creating folder '{0}': {1}</value>
|
||||||
|
<comment>{0} Name of the folder, {1} exception message</comment>
|
||||||
|
</data>
|
||||||
|
<data name="ErrorExtraWhitespacesInMultiValues" xml:space="preserve">
|
||||||
|
<value>Multivalue field: '{0}' contains trailing or leading whitespaces.</value>
|
||||||
|
<comment>{0}: multivalue string</comment>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
|
@ -581,4 +581,12 @@
|
||||||
<data name="TemplatesSynchronizationError" xml:space="preserve">
|
<data name="TemplatesSynchronizationError" xml:space="preserve">
|
||||||
<value>Error synchronizing templates.</value>
|
<value>Error synchronizing templates.</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="ErrorCreatingFolder" xml:space="preserve">
|
||||||
|
<value>Error creating folder '{0}': {1}</value>
|
||||||
|
<comment>{0} Name of the folder, {1} exception message</comment>
|
||||||
|
</data>
|
||||||
|
<data name="ErrorExtraWhitespacesInMultiValues" xml:space="preserve">
|
||||||
|
<value>Multivalue field: '{0}' contains trailing or leading whitespaces.</value>
|
||||||
|
<comment>{0}: multivalue string</comment>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
|
@ -581,4 +581,12 @@
|
||||||
<data name="TemplatesSynchronizationError" xml:space="preserve">
|
<data name="TemplatesSynchronizationError" xml:space="preserve">
|
||||||
<value>Error synchronizing templates.</value>
|
<value>Error synchronizing templates.</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="ErrorCreatingFolder" xml:space="preserve">
|
||||||
|
<value>Error creating folder '{0}': {1}</value>
|
||||||
|
<comment>{0} Name of the folder, {1} exception message</comment>
|
||||||
|
</data>
|
||||||
|
<data name="ErrorExtraWhitespacesInMultiValues" xml:space="preserve">
|
||||||
|
<value>Multivalue field: '{0}' contains trailing or leading whitespaces.</value>
|
||||||
|
<comment>{0}: multivalue string</comment>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
|
@ -581,4 +581,12 @@ Nie można zinterpretować następujących zmian: {2}
|
||||||
<data name="TemplatesSynchronizationError" xml:space="preserve">
|
<data name="TemplatesSynchronizationError" xml:space="preserve">
|
||||||
<value>Error synchronizing templates.</value>
|
<value>Error synchronizing templates.</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="ErrorCreatingFolder" xml:space="preserve">
|
||||||
|
<value>Error creating folder '{0}': {1}</value>
|
||||||
|
<comment>{0} Name of the folder, {1} exception message</comment>
|
||||||
|
</data>
|
||||||
|
<data name="ErrorExtraWhitespacesInMultiValues" xml:space="preserve">
|
||||||
|
<value>Multivalue field: '{0}' contains trailing or leading whitespaces.</value>
|
||||||
|
<comment>{0}: multivalue string</comment>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
|
@ -581,4 +581,12 @@ As seguintes alterações não puderam ser integradas: {2}
|
||||||
<data name="TemplatesSynchronizationError" xml:space="preserve">
|
<data name="TemplatesSynchronizationError" xml:space="preserve">
|
||||||
<value>Error synchronizing templates.</value>
|
<value>Error synchronizing templates.</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="ErrorCreatingFolder" xml:space="preserve">
|
||||||
|
<value>Error creating folder '{0}': {1}</value>
|
||||||
|
<comment>{0} Name of the folder, {1} exception message</comment>
|
||||||
|
</data>
|
||||||
|
<data name="ErrorExtraWhitespacesInMultiValues" xml:space="preserve">
|
||||||
|
<value>Multivalue field: '{0}' contains trailing or leading whitespaces.</value>
|
||||||
|
<comment>{0}: multivalue string</comment>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
|
@ -158,11 +158,11 @@
|
||||||
<comment>{0}: Source File Path, {1}: Destination folder name, {2}: Error</comment>
|
<comment>{0}: Source File Path, {1}: Destination folder name, {2}: Error</comment>
|
||||||
</data>
|
</data>
|
||||||
<data name="FsSafeDeleteDirectoryMessage" xml:space="preserve">
|
<data name="FsSafeDeleteDirectoryMessage" xml:space="preserve">
|
||||||
<value>The folder {0} can't be delete. Error: {1}</value>
|
<value>The folder {0} can't be deleted. Error: {1}</value>
|
||||||
<comment>{0}: Folder Name, {1}: Error</comment>
|
<comment>{0}: Folder Name, {1}: Error</comment>
|
||||||
</data>
|
</data>
|
||||||
<data name="FsSafeDeleteFileMessage" xml:space="preserve">
|
<data name="FsSafeDeleteFileMessage" xml:space="preserve">
|
||||||
<value>The file {0} can't be delete. Error: {1}</value>
|
<value>The file {0} can't be deleted. Error: {1}</value>
|
||||||
<comment>{0}: File Path, {1}: Error</comment>
|
<comment>{0}: File Path, {1}: Error</comment>
|
||||||
</data>
|
</data>
|
||||||
<data name="FsSafeMoveDirectoryMessage" xml:space="preserve">
|
<data name="FsSafeMoveDirectoryMessage" xml:space="preserve">
|
||||||
|
@ -438,7 +438,7 @@ The following changes could not be integrated: {2}
|
||||||
<value>Templates local path is empty.</value>
|
<value>Templates local path is empty.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="FsSafeRenameDirectoryMessage" xml:space="preserve">
|
<data name="FsSafeRenameDirectoryMessage" xml:space="preserve">
|
||||||
<value>The folder {0} can't be rename. Error: {1}</value>
|
<value>The folder {0} can't be renamed. Error: {1}</value>
|
||||||
<comment>{0}: Folder Name, {1}: Error</comment>
|
<comment>{0}: Folder Name, {1}: Error</comment>
|
||||||
</data>
|
</data>
|
||||||
<data name="TemplatesSynchronizationErrorDownloadingConfig" xml:space="preserve">
|
<data name="TemplatesSynchronizationErrorDownloadingConfig" xml:space="preserve">
|
||||||
|
@ -581,4 +581,12 @@ The following changes could not be integrated: {2}
|
||||||
<data name="TemplatesSynchronizationError" xml:space="preserve">
|
<data name="TemplatesSynchronizationError" xml:space="preserve">
|
||||||
<value>Error synchronizing templates.</value>
|
<value>Error synchronizing templates.</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="ErrorCreatingFolder" xml:space="preserve">
|
||||||
|
<value>Error creating folder '{0}': {1}</value>
|
||||||
|
<comment>{0} Name of the folder, {1} exception message</comment>
|
||||||
|
</data>
|
||||||
|
<data name="ErrorExtraWhitespacesInMultiValues" xml:space="preserve">
|
||||||
|
<value>Multivalue field: '{0}' contains trailing or leading whitespaces.</value>
|
||||||
|
<comment>{0}: multivalue string</comment>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
|
@ -581,4 +581,12 @@
|
||||||
<data name="TemplatesSynchronizationError" xml:space="preserve">
|
<data name="TemplatesSynchronizationError" xml:space="preserve">
|
||||||
<value>Error synchronizing templates.</value>
|
<value>Error synchronizing templates.</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="ErrorCreatingFolder" xml:space="preserve">
|
||||||
|
<value>Error creating folder '{0}': {1}</value>
|
||||||
|
<comment>{0} Name of the folder, {1} exception message</comment>
|
||||||
|
</data>
|
||||||
|
<data name="ErrorExtraWhitespacesInMultiValues" xml:space="preserve">
|
||||||
|
<value>Multivalue field: '{0}' contains trailing or leading whitespaces.</value>
|
||||||
|
<comment>{0}: multivalue string</comment>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
|
@ -581,4 +581,12 @@ Aşağıdaki değişiklikler tümleştirilemedi: {2}
|
||||||
<data name="TemplatesSynchronizationError" xml:space="preserve">
|
<data name="TemplatesSynchronizationError" xml:space="preserve">
|
||||||
<value>Error synchronizing templates.</value>
|
<value>Error synchronizing templates.</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="ErrorCreatingFolder" xml:space="preserve">
|
||||||
|
<value>Error creating folder '{0}': {1}</value>
|
||||||
|
<comment>{0} Name of the folder, {1} exception message</comment>
|
||||||
|
</data>
|
||||||
|
<data name="ErrorExtraWhitespacesInMultiValues" xml:space="preserve">
|
||||||
|
<value>Multivalue field: '{0}' contains trailing or leading whitespaces.</value>
|
||||||
|
<comment>{0}: multivalue string</comment>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
|
@ -581,4 +581,12 @@
|
||||||
<data name="TemplatesSynchronizationError" xml:space="preserve">
|
<data name="TemplatesSynchronizationError" xml:space="preserve">
|
||||||
<value>Error synchronizing templates.</value>
|
<value>Error synchronizing templates.</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="ErrorCreatingFolder" xml:space="preserve">
|
||||||
|
<value>Error creating folder '{0}': {1}</value>
|
||||||
|
<comment>{0} Name of the folder, {1} exception message</comment>
|
||||||
|
</data>
|
||||||
|
<data name="ErrorExtraWhitespacesInMultiValues" xml:space="preserve">
|
||||||
|
<value>Multivalue field: '{0}' contains trailing or leading whitespaces.</value>
|
||||||
|
<comment>{0}: multivalue string</comment>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
|
@ -581,4 +581,12 @@
|
||||||
<data name="TemplatesSynchronizationError" xml:space="preserve">
|
<data name="TemplatesSynchronizationError" xml:space="preserve">
|
||||||
<value>Error synchronizing templates.</value>
|
<value>Error synchronizing templates.</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="ErrorCreatingFolder" xml:space="preserve">
|
||||||
|
<value>Error creating folder '{0}': {1}</value>
|
||||||
|
<comment>{0} Name of the folder, {1} exception message</comment>
|
||||||
|
</data>
|
||||||
|
<data name="ErrorExtraWhitespacesInMultiValues" xml:space="preserve">
|
||||||
|
<value>Multivalue field: '{0}' contains trailing or leading whitespaces.</value>
|
||||||
|
<comment>{0}: multivalue string</comment>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
|
@ -7,11 +7,6 @@
|
||||||
<Configurations>Debug;Release;Analyze</Configurations>
|
<Configurations>Debug;Release;Analyze</Configurations>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<EmbeddedResource Remove="TestData\NewFolder\**" />
|
|
||||||
<None Remove="TestData\NewFolder\**" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Remove="TestData\Templates\test\itemNameValidation.config.json" />
|
<None Remove="TestData\Templates\test\itemNameValidation.config.json" />
|
||||||
<None Remove="TestData\Templates\test\projectNameValidation.config.json" />
|
<None Remove="TestData\Templates\test\projectNameValidation.config.json" />
|
||||||
|
@ -99,7 +94,7 @@
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.10.0" />
|
||||||
<PackageReference Include="System.Configuration.ConfigurationManager" Version="4.7.0" />
|
<PackageReference Include="System.Configuration.ConfigurationManager" Version="4.7.0" />
|
||||||
<PackageReference Include="xunit" Version="2.4.1" />
|
<PackageReference Include="xunit" Version="2.4.1" />
|
||||||
<PackageReference Include="xunit.runner.console" Version="2.4.1">
|
<PackageReference Include="xunit.runner.console" Version="2.4.1">
|
||||||
|
@ -163,8 +158,24 @@
|
||||||
<Compile Include="Diagnostics\TelemetryFixture.cs" />
|
<Compile Include="Diagnostics\TelemetryFixture.cs" />
|
||||||
<Compile Include="Diagnostics\TelemetryServiceTest.cs" />
|
<Compile Include="Diagnostics\TelemetryServiceTest.cs" />
|
||||||
<Compile Include="Diagnostics\TestHealthWriter.cs" />
|
<Compile Include="Diagnostics\TestHealthWriter.cs" />
|
||||||
|
<Compile Include="Extensions\IEnumerableExtensionsTests.cs" />
|
||||||
<Compile Include="Extensions\StringExtensions.cs" />
|
<Compile Include="Extensions\StringExtensions.cs" />
|
||||||
<Compile Include="Gen\GenComposerTests.cs" />
|
<Compile Include="Extensions\TemplateTypeExtensionsTests.cs" />
|
||||||
|
<Compile Include="Extensions\VersionExtensionsTests.cs" />
|
||||||
|
<Compile Include="Extensions\StringExtensionsTests.cs" />
|
||||||
|
<Compile Include="Extensions\DateTimeExtensionsTests.cs" />
|
||||||
|
<Compile Include="Extensions\DictionaryExtensionsTests.cs" />
|
||||||
|
<Compile Include="Gen\GenComposerTests.cs" />
|
||||||
|
<Compile Include="Helpers\FsTests\GetExistingFolderNamesTests.cs" />
|
||||||
|
<Compile Include="Helpers\FSTestsFixture.cs" />
|
||||||
|
<Compile Include="Helpers\FsTests\SafeMoveFileTests.cs" />
|
||||||
|
<Compile Include="Helpers\FsTests\SafeDeleteFileTests.cs" />
|
||||||
|
<Compile Include="Helpers\FsTests\SafeRenameDirectoryTests.cs" />
|
||||||
|
<Compile Include="Helpers\FsTests\SafeDeleteDirectoryTests.cs" />
|
||||||
|
<Compile Include="Helpers\FsTests\SafeCopyFileTests.cs" />
|
||||||
|
<Compile Include="Helpers\FsTests\EnsureFileEditableTests.cs" />
|
||||||
|
<Compile Include="Helpers\FsTests\EnsureFolderExistsTests.cs" />
|
||||||
|
<Compile Include="Helpers\FileHelpersTests.cs" />
|
||||||
<Compile Include="Naming\ItemNameServiceTests.cs" />
|
<Compile Include="Naming\ItemNameServiceTests.cs" />
|
||||||
<Compile Include="Naming\ProjectNameServiceTests.cs" />
|
<Compile Include="Naming\ProjectNameServiceTests.cs" />
|
||||||
<Compile Include="Naming\Validators\DefaultNamesValidatorTests.cs" />
|
<Compile Include="Naming\Validators\DefaultNamesValidatorTests.cs" />
|
||||||
|
|
|
@ -0,0 +1,80 @@
|
||||||
|
// Licensed to the .NET Foundation under one or more agreements.
|
||||||
|
// The .NET Foundation licenses this file to you under the MIT license.
|
||||||
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Microsoft.Templates.Core.Test.Extensions
|
||||||
|
{
|
||||||
|
[Trait("ExecutionSet", "Minimum")]
|
||||||
|
public class DateTimeExtensionsTests
|
||||||
|
{
|
||||||
|
private readonly DateTime date;
|
||||||
|
|
||||||
|
public DateTimeExtensionsTests()
|
||||||
|
{
|
||||||
|
date = new DateTime(2000, 1, 2, 3, 4, 5, 6);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void FormatAsDateForFilePath_ShouldReturnCorrectStringDate()
|
||||||
|
{
|
||||||
|
var factData = date;
|
||||||
|
|
||||||
|
var expected = "20000102";
|
||||||
|
|
||||||
|
var result = factData.FormatAsDateForFilePath();
|
||||||
|
|
||||||
|
Assert.Equal(expected: expected, actual: result);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void FormatAsFullDateTime_ShouldReturnCorrectStringDate()
|
||||||
|
{
|
||||||
|
var factData = date;
|
||||||
|
|
||||||
|
var expected = "2000-01-02 03:04:05.006";
|
||||||
|
|
||||||
|
var result = factData.FormatAsFullDateTime();
|
||||||
|
|
||||||
|
Assert.Equal(result, expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void FormatAsTime_ShouldReturnCorrectStringDate()
|
||||||
|
{
|
||||||
|
var factData = date;
|
||||||
|
|
||||||
|
var expected = "03:04:05.006";
|
||||||
|
|
||||||
|
var result = factData.FormatAsTime();
|
||||||
|
|
||||||
|
Assert.Equal(result, expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void FormatAsShortDateTime_ShouldReturnCorrectStringDate()
|
||||||
|
{
|
||||||
|
var factData = date;
|
||||||
|
|
||||||
|
var expected = "20000102_030405";
|
||||||
|
|
||||||
|
var result = factData.FormatAsShortDateTime();
|
||||||
|
|
||||||
|
Assert.Equal(result, expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void FormatAsDateHoursMinutes_ShouldReturnCorrectStringDate()
|
||||||
|
{
|
||||||
|
var factData = date;
|
||||||
|
|
||||||
|
var expected = "02030405";
|
||||||
|
|
||||||
|
var result = factData.FormatAsDateHoursMinutes();
|
||||||
|
|
||||||
|
Assert.Equal(result, expected);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,111 @@
|
||||||
|
// Licensed to the .NET Foundation under one or more agreements.
|
||||||
|
// The .NET Foundation licenses this file to you under the MIT license.
|
||||||
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Microsoft.Templates.Core.Composition;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Microsoft.Templates.Core.Test.Extensions
|
||||||
|
{
|
||||||
|
[Trait("ExecutionSet", "Minimum")]
|
||||||
|
public class DictionaryExtensionsTests
|
||||||
|
{
|
||||||
|
private const int MAX = 100;
|
||||||
|
private readonly Random random;
|
||||||
|
private readonly Dictionary<string, string> dictionaryOfStrings;
|
||||||
|
private readonly Dictionary<string, QueryableProperty> dictionaryOfQueryable;
|
||||||
|
|
||||||
|
public DictionaryExtensionsTests()
|
||||||
|
{
|
||||||
|
random = new Random();
|
||||||
|
dictionaryOfStrings = new Dictionary<string, string>();
|
||||||
|
dictionaryOfQueryable = new Dictionary<string, QueryableProperty>();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetUpStringData(int items)
|
||||||
|
{
|
||||||
|
for (var i = 0; i < items; i++)
|
||||||
|
{
|
||||||
|
dictionaryOfStrings.Add($"key{i + 1}", $"value{i + 1}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void SafeGet_DictionaryOfStrings_NotFound_ShouldReturnDefault()
|
||||||
|
{
|
||||||
|
string expected = null;
|
||||||
|
|
||||||
|
var actual = dictionaryOfStrings.SafeGet("test");
|
||||||
|
|
||||||
|
Assert.Equal(expected, actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void SafeGet_DictionaryOfStrings_NotFound_ShouldReturnConfiguredDefault()
|
||||||
|
{
|
||||||
|
string expected = "default";
|
||||||
|
|
||||||
|
var actual = dictionaryOfStrings.SafeGet("test", "default");
|
||||||
|
|
||||||
|
Assert.Equal(expected, actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void SafeGet_DictionaryOfStrings_Found_ShouldReturnItem()
|
||||||
|
{
|
||||||
|
var randomItemsNumber = random.Next(MAX);
|
||||||
|
SetUpStringData(randomItemsNumber);
|
||||||
|
|
||||||
|
var expected = $"value{randomItemsNumber}";
|
||||||
|
|
||||||
|
var actual = dictionaryOfStrings.SafeGet($"key{randomItemsNumber}");
|
||||||
|
|
||||||
|
Assert.Equal(expected, actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetUpQueryableData(int items)
|
||||||
|
{
|
||||||
|
for (var i = 0; i < items; i++)
|
||||||
|
{
|
||||||
|
dictionaryOfQueryable.Add($"key{i + 1}", new QueryableProperty($"name{i + 1}", $"value{i + 1}"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void SafeGet_DictionaryOfQueryable_NotFound_ShouldReturnDefault()
|
||||||
|
{
|
||||||
|
QueryableProperty expected = null;
|
||||||
|
|
||||||
|
var actual = dictionaryOfQueryable.SafeGet("test");
|
||||||
|
|
||||||
|
Assert.Equal(expected, actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void SafeGet_DictionaryOfQueryable_NotFound_ShouldReturnConfiguredDefault()
|
||||||
|
{
|
||||||
|
QueryableProperty expected = QueryableProperty.Empty;
|
||||||
|
|
||||||
|
var actual = dictionaryOfQueryable.SafeGet("test", QueryableProperty.Empty);
|
||||||
|
|
||||||
|
Assert.Equal(expected.Name, actual.Name);
|
||||||
|
Assert.Equal(expected.Value, actual.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void SafeGet_DictionaryOfQueryable_Found_ShouldReturnItem()
|
||||||
|
{
|
||||||
|
var randomItemsNumber = random.Next(MAX);
|
||||||
|
SetUpQueryableData(randomItemsNumber);
|
||||||
|
|
||||||
|
var expected = new QueryableProperty($"name{randomItemsNumber}", $"value{randomItemsNumber}");
|
||||||
|
|
||||||
|
var actual = dictionaryOfQueryable.SafeGet($"key{randomItemsNumber}");
|
||||||
|
|
||||||
|
Assert.Equal(expected.Name, actual.Name);
|
||||||
|
Assert.Equal(expected.Value, actual.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,97 @@
|
||||||
|
// Licensed to the .NET Foundation under one or more agreements.
|
||||||
|
// The .NET Foundation licenses this file to you under the MIT license.
|
||||||
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Microsoft.Templates.Core.Test.Extensions
|
||||||
|
{
|
||||||
|
[Trait("ExecutionSet", "Minimum")]
|
||||||
|
public class IEnumerableExtensionsTests
|
||||||
|
{
|
||||||
|
[Theory]
|
||||||
|
[InlineData(new string[0], "public void SomeMethod()", 0)]
|
||||||
|
[InlineData(new string[0], "public void SomeMethod()", 5)]
|
||||||
|
[InlineData(null, "public void SomeMethod()", 0)]
|
||||||
|
[InlineData(null, "public void SomeMethod()", 5)]
|
||||||
|
[InlineData(new[] { " " }, "public void SomeMethod()", 0)]
|
||||||
|
[InlineData(new[] { " " }, "public void SomeMethod()", 5)]
|
||||||
|
public void SafeIndexOf_NoAvailableLinesToMatch_ShouldReturnNotFound(IEnumerable<string> lines, string lineToMatch, int linesToSkip)
|
||||||
|
{
|
||||||
|
var expected = -1;
|
||||||
|
var actual = lines.SafeIndexOf(lineToMatch, linesToSkip);
|
||||||
|
|
||||||
|
Assert.Equal(expected, actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData(new string[0], "public void SomeMethod()")]
|
||||||
|
[InlineData(new[] { "public void SomeMetod()", "{", "}" }, "public void SomeMethod()")]
|
||||||
|
[InlineData(new[] { "public void SomeMethod()", "{", "}" }, "no matching line")]
|
||||||
|
[InlineData(new[] { " public void SomeMethod()", "{", "}" }, "public void SomeMethod()")]
|
||||||
|
[InlineData(new[] { "", "", "public void SomeMethod()", "{", "}" }, "public void SmeMethod()")]
|
||||||
|
public void SafeIndexOf_NoMatchingLinesFound_ShouldReturnNotFound(IEnumerable<string> lines, string linesToMatch)
|
||||||
|
{
|
||||||
|
var expected = -1;
|
||||||
|
var linesToSkip = 0;
|
||||||
|
var actual = lines.SafeIndexOf(linesToMatch, linesToSkip);
|
||||||
|
|
||||||
|
Assert.Equal(expected, actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData(new[] { "public void SomeMethod()", "{", "}" }, "no matching line", -1)]
|
||||||
|
[InlineData(new[] { "public void SomeMethod()", "{", "}" }, "public void SomeMethod()", 0)]
|
||||||
|
[InlineData(new[] { "", "", "public void SomeMethod()", "{", "}" }, "public void SomeMethod()", 2)]
|
||||||
|
public void SafeIndexOf_NoLinesToSkip_ShouldReturnIndexOfMatchingLine(IEnumerable<string> lines, string lineToMatch, int indexOfLine)
|
||||||
|
{
|
||||||
|
var actual = lines.SafeIndexOf(lineToMatch, 0);
|
||||||
|
|
||||||
|
Assert.Equal(indexOfLine, actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData(new[] { "public void SomeMethod()", "{", "}" }, "public void SomeMethod()", 0)]
|
||||||
|
[InlineData(new[] { "public void SomeMethod()", "{", "}" }, "{", 1)]
|
||||||
|
[InlineData(new[] { " ", "public void SomeMethod()", "{", "}" }, "{", 2)]
|
||||||
|
[InlineData(new[] { "public void SomeMethod()", "{", "}", "//line to match" }, "//line to match", 3)]
|
||||||
|
public void SafeIndexOf_SkipLinesIsNegativeNumber_ShouldReturnIndexOfMatchingLine(IEnumerable<string> lines, string lineToMatch, int indexOfLine)
|
||||||
|
{
|
||||||
|
var actual = lines.SafeIndexOf(lineToMatch, -1);
|
||||||
|
|
||||||
|
Assert.Equal(indexOfLine, actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData(new[] { "public void SomeMethod()", "", "{", "}" }, "public void SomeMethod()", 0, 0)]
|
||||||
|
[InlineData(new[] { "public void SomeMethod()", "", "{", "}" }, "public void SomeMethod()", 1, -1)]
|
||||||
|
[InlineData(new[] { "", "", "public void SomeMethod()", "{", "}" }, "public void SomeMethod()", 1, 2)]
|
||||||
|
[InlineData(new[] { "public void SomeMethod()", "{", "//line to match", "}", "//line to match" }, "//line to match", 1, 2)]
|
||||||
|
[InlineData(new[] { "public void SomeMethod()", "{", "//line to match", "}", "//line to match" }, "//line to match", 4, 4)]
|
||||||
|
[InlineData(new[] { "public void SomeMethod()", "{", "//line to match", "}", "//line to match" }, "//line to match", 5, -1)]
|
||||||
|
[InlineData(new[] { "public void SomeMethod()", "{", "}", "//line to match" }, "//line to match", 1, 3)]
|
||||||
|
[InlineData(new[] { "public void SomeMethod()", "{", "}", "//line to match" }, "//line to match", 4, -1)]
|
||||||
|
[InlineData(new[] { "", " ", "public void SomeMethod()", "//line to match", "{ ", "}", "//line to match" }, "//line to match", 1, 3)]
|
||||||
|
[InlineData(new[] { "//line to match", " ", "public void SomeMethod()", "//line to match", "{ ", "}", "//line to match" }, "//line to match", 1, 3)]
|
||||||
|
public void SafeIndexOf_SkippingLines_TakeIntoAccountWhiteLines_ShouldReturnIndexOfMatchingLine(IEnumerable<string> lines, string lineToMatch, int linesToSkip, int indexOfMatchingLine)
|
||||||
|
{
|
||||||
|
var actual = lines.SafeIndexOf(lineToMatch, linesToSkip, false);
|
||||||
|
|
||||||
|
Assert.Equal(indexOfMatchingLine, actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData(new[] { "public SomeClass(/*{[{*/ISomeService someService/*}]}*/)", "{", "}" }, "public SomeCass(", -1)]
|
||||||
|
[InlineData(new[] { "public SomeClass(/*{[{*/ISomeService someService/*}]}*/)", "{", "}" }, "public SomeClass(", 0)]
|
||||||
|
[InlineData(new[] { " public SomeClass(/*{[{*/ISomeService someService/*}]}*/)", "{", "}" }, "public SomeClass(", -1)]
|
||||||
|
[InlineData(new[] { "", "public SomeClass(/*{[{*/ISomeService someService/*}]}*/)", "{", "}" }, "public SomeClass(", 1)]
|
||||||
|
[InlineData(new[] { "", " ", "public SomeClass(/*{[{*/ISomeService someService/*}]}*/)", "{", "}" }, "public SomeClass(", 2)]
|
||||||
|
public void SafeIndexOf_ReplaceInline_CompareUpToItemLenghtIsTrue_ShouldReturnIndexOfMatchingLine(IEnumerable<string> lines, string lineToMatch, int indexOfMatchingLine)
|
||||||
|
{
|
||||||
|
var actual = lines.SafeIndexOf(lineToMatch, 0, true, true);
|
||||||
|
|
||||||
|
Assert.Equal(indexOfMatchingLine, actual);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,135 @@
|
||||||
|
// Licensed to the .NET Foundation under one or more agreements.
|
||||||
|
// The .NET Foundation licenses this file to you under the MIT license.
|
||||||
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Microsoft.Templates.Core.Test.Extensions
|
||||||
|
{
|
||||||
|
[Trait("ExecutionSet", "Minimum")]
|
||||||
|
public class StringExtensionsTests
|
||||||
|
{
|
||||||
|
[Theory]
|
||||||
|
[InlineData("")]
|
||||||
|
[InlineData(" ")]
|
||||||
|
[InlineData(null)]
|
||||||
|
[InlineData("||")]
|
||||||
|
[InlineData("|")]
|
||||||
|
public void GetMultiValue_NoValue_ShouldReturnEmptyArray(string value)
|
||||||
|
{
|
||||||
|
var expected = Array.Empty<string>();
|
||||||
|
|
||||||
|
var actual = value.GetMultiValue();
|
||||||
|
|
||||||
|
Assert.Equal(expected, actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData("One|", new string[] { "One" })]
|
||||||
|
[InlineData("One|Two", new string[] { "One", "Two" })]
|
||||||
|
[InlineData("One Two|", new string[] { "One Two" })]
|
||||||
|
[InlineData("One|Two Three", new string[] { "One", "Two Three" })]
|
||||||
|
[InlineData("One Two|Three", new string[] { "One Two", "Three" })]
|
||||||
|
[InlineData("One|Two||Three", new string[] { "One", "Two", "Three" })]
|
||||||
|
public void GetMultiValue_HasValue_ShouldReturnExpected(string value, string[] expected)
|
||||||
|
{
|
||||||
|
var actual = value.GetMultiValue();
|
||||||
|
|
||||||
|
Assert.Equal(expected, actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData("| ")]
|
||||||
|
[InlineData("One| ")]
|
||||||
|
[InlineData("One |Two")]
|
||||||
|
[InlineData(" One|Two")]
|
||||||
|
[InlineData(" One|Two")]
|
||||||
|
[InlineData("One |Two")]
|
||||||
|
[InlineData(" One Two|")]
|
||||||
|
[InlineData("One Two |")]
|
||||||
|
[InlineData("One|Two|| Three")]
|
||||||
|
[InlineData("One|Two| |Three")]
|
||||||
|
[InlineData("One|Two||Three ")]
|
||||||
|
[InlineData("One| One Two||Three")]
|
||||||
|
[InlineData("One|One Two ||Three")]
|
||||||
|
[InlineData(" One Two|Three||Four")]
|
||||||
|
[InlineData("One Two |Three||Four")]
|
||||||
|
[InlineData("One|Two|| Three Four")]
|
||||||
|
[InlineData("One|Two||Three Four ")]
|
||||||
|
public void GetMultiValue_ValueContainsTrailingSpaces_ShouldThrowInvalidDataException(string value)
|
||||||
|
{
|
||||||
|
Assert.Throws<InvalidDataException>(() => { value.GetMultiValue(); });
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData("One|Two")]
|
||||||
|
[InlineData("|One|Two|")]
|
||||||
|
[InlineData("One||Two|Three")]
|
||||||
|
[InlineData("One||Two Three|Four")]
|
||||||
|
[InlineData("One||Two Three")]
|
||||||
|
[InlineData("One Two||Two Three")]
|
||||||
|
public void IsMultiValue_IfSeveralValues_ShouldReturnTrue(string value)
|
||||||
|
{
|
||||||
|
var actual = value.IsMultiValue();
|
||||||
|
|
||||||
|
Assert.True(actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData(" One")]
|
||||||
|
[InlineData("One ")]
|
||||||
|
[InlineData(" One|")]
|
||||||
|
[InlineData("One |")]
|
||||||
|
[InlineData("One| ")]
|
||||||
|
[InlineData("One| Two")]
|
||||||
|
[InlineData("One|Two ")]
|
||||||
|
[InlineData(" |One|Two|")]
|
||||||
|
[InlineData(" |One|Two Three|")]
|
||||||
|
[InlineData(" |One|Two Three|Four")]
|
||||||
|
[InlineData("|One|Two Three |Four")]
|
||||||
|
[InlineData("|One|Two Three|Four ")]
|
||||||
|
[InlineData("One| | Two|Three")]
|
||||||
|
public void IsMultiValue_ValueContainsTrailingSpaces_ShouldThrowInvalidDataException(string value)
|
||||||
|
{
|
||||||
|
Assert.Throws<InvalidDataException>(() => { value.IsMultiValue(); });
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData(null)]
|
||||||
|
[InlineData("")]
|
||||||
|
[InlineData(" ")]
|
||||||
|
[InlineData("||")]
|
||||||
|
[InlineData("One")]
|
||||||
|
[InlineData("One|")]
|
||||||
|
public void IsMultiValue_SingleOrNoValue_ShouldReturnFalse(string value)
|
||||||
|
{
|
||||||
|
var actual = value.IsMultiValue();
|
||||||
|
|
||||||
|
Assert.False(actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData("hello this is a statement", 0)]
|
||||||
|
[InlineData(" hello this is a statement", 1)]
|
||||||
|
[InlineData(" hello this is a statement", 3)]
|
||||||
|
public void GetLeadingTrivia_ShouldCountInitialWhitespacesCorrectly(string value, int expected)
|
||||||
|
{
|
||||||
|
var actual = value.GetLeadingTrivia();
|
||||||
|
|
||||||
|
Assert.Equal(expected, actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData("hello this is a statement", 0, "hello this is a statement")]
|
||||||
|
[InlineData("hello this is a statement", 1, " hello this is a statement")]
|
||||||
|
[InlineData("hello this is a statement", 3, " hello this is a statement")]
|
||||||
|
public void WithLeadingTrivia_Should(string value, int triviaCount, string expected)
|
||||||
|
{
|
||||||
|
var actual = value.WithLeadingTrivia(triviaCount);
|
||||||
|
|
||||||
|
Assert.Equal(expected, actual);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,89 @@
|
||||||
|
// Licensed to the .NET Foundation under one or more agreements.
|
||||||
|
// The .NET Foundation licenses this file to you under the MIT license.
|
||||||
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
|
using Microsoft.Templates.Core.Extensions;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Microsoft.Templates.Core.Test.Extensions
|
||||||
|
{
|
||||||
|
[Trait("ExecutionSet", "Minimum")]
|
||||||
|
public class TemplateTypeExtensionsTests
|
||||||
|
{
|
||||||
|
private const int PROJECT = 0;
|
||||||
|
private const int PAGE = 1;
|
||||||
|
private const int FEATURE = 2;
|
||||||
|
private const int SERVICE = 3;
|
||||||
|
private const int TESTING = 4;
|
||||||
|
private const int COMPOSITION = 5;
|
||||||
|
private const int UNSPECIFIED = 6;
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData(PAGE)]
|
||||||
|
[InlineData(FEATURE)]
|
||||||
|
[InlineData(SERVICE)]
|
||||||
|
[InlineData(TESTING)]
|
||||||
|
public void IsItemTemplate_ShouldBeTrue(int templateTypeId)
|
||||||
|
{
|
||||||
|
TemplateType templateType = (TemplateType)templateTypeId;
|
||||||
|
var actual = templateType.IsItemTemplate();
|
||||||
|
|
||||||
|
Assert.True(actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData(PROJECT)]
|
||||||
|
[InlineData(COMPOSITION)]
|
||||||
|
[InlineData(UNSPECIFIED)]
|
||||||
|
public void IsItemTemplate_ShouldBeFalse(int templateTypeId)
|
||||||
|
{
|
||||||
|
TemplateType templateType = (TemplateType)templateTypeId;
|
||||||
|
var actual = templateType.IsItemTemplate();
|
||||||
|
|
||||||
|
Assert.False(actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
private const int ADDPAGE = 1;
|
||||||
|
private const int ADDFEATURE = 2;
|
||||||
|
private const int ADDSERVICE = 3;
|
||||||
|
private const int ADDTESTING = 4;
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData(PAGE)]
|
||||||
|
[InlineData(FEATURE)]
|
||||||
|
[InlineData(SERVICE)]
|
||||||
|
[InlineData(TESTING)]
|
||||||
|
public void GetWizardType_ShouldNotBeNull(int templateTypeId)
|
||||||
|
{
|
||||||
|
TemplateType templateType = (TemplateType)templateTypeId;
|
||||||
|
var actual = templateType.GetWizardType();
|
||||||
|
|
||||||
|
Assert.NotNull(actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData(PAGE, ADDPAGE)]
|
||||||
|
[InlineData(FEATURE, ADDFEATURE)]
|
||||||
|
[InlineData(SERVICE, ADDSERVICE)]
|
||||||
|
[InlineData(TESTING, ADDTESTING)]
|
||||||
|
public void GetWizardType_IsItemTemplate_ShouldMatchAValidWizardType(int templateTypeId, int? wizardTypeId)
|
||||||
|
{
|
||||||
|
TemplateType templateType = (TemplateType)templateTypeId;
|
||||||
|
var actual = templateType.GetWizardType();
|
||||||
|
|
||||||
|
Assert.Equal(wizardTypeId, (int?)actual.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData(PROJECT)]
|
||||||
|
[InlineData(COMPOSITION)]
|
||||||
|
[InlineData(UNSPECIFIED)]
|
||||||
|
public void GetWizardType_NotItemTemplate_ShouldReturnNull(int templateTypeId)
|
||||||
|
{
|
||||||
|
TemplateType templateType = (TemplateType)templateTypeId;
|
||||||
|
var actual = templateType.GetWizardType();
|
||||||
|
|
||||||
|
Assert.Null(actual);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,111 @@
|
||||||
|
// Licensed to the .NET Foundation under one or more agreements.
|
||||||
|
// The .NET Foundation licenses this file to you under the MIT license.
|
||||||
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Microsoft.Templates.Core.Test.Extensions
|
||||||
|
{
|
||||||
|
[Trait("ExecutionSet", "Minimum")]
|
||||||
|
public class VersionExtensionsTests
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
public void IsNull_IsNullVersion_ShouldReturnTrue()
|
||||||
|
{
|
||||||
|
Version factData = null;
|
||||||
|
var actual = factData.IsNull();
|
||||||
|
|
||||||
|
Assert.True(actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void IsNull_NotNullVersion_ShouldReturnFalse()
|
||||||
|
{
|
||||||
|
Version factData = new Version();
|
||||||
|
var actual = factData.IsNull();
|
||||||
|
|
||||||
|
Assert.False(actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void IsZero_IsNullVersion_ShouldReturnFalse()
|
||||||
|
{
|
||||||
|
Version factData = null;
|
||||||
|
var actual = factData.IsZero();
|
||||||
|
|
||||||
|
Assert.False(actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[MemberData(nameof(ZeroData))]
|
||||||
|
public void IsZero_ZeroVersion_ShouldReturnTrue(Version version)
|
||||||
|
{
|
||||||
|
var actual = version.IsZero();
|
||||||
|
|
||||||
|
Assert.True(actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[MemberData(nameof(NonZeroVersionData))]
|
||||||
|
public void IsZero_NonZeroVersion_ShouldReturnFalse(Version version)
|
||||||
|
{
|
||||||
|
var actual = version.IsZero();
|
||||||
|
|
||||||
|
Assert.False(actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IEnumerable<object[]> ZeroData => new List<object[]>()
|
||||||
|
{
|
||||||
|
new object[]
|
||||||
|
{
|
||||||
|
new Version(),
|
||||||
|
},
|
||||||
|
new object[]
|
||||||
|
{
|
||||||
|
new Version("0.0"),
|
||||||
|
},
|
||||||
|
new object[]
|
||||||
|
{
|
||||||
|
new Version(0, 0),
|
||||||
|
},
|
||||||
|
new object[]
|
||||||
|
{
|
||||||
|
new Version(0, 0, 0),
|
||||||
|
},
|
||||||
|
new object[]
|
||||||
|
{
|
||||||
|
new Version(0, 0, 0, 0),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
public static IEnumerable<object[]> NonZeroVersionData => new List<object[]>()
|
||||||
|
{
|
||||||
|
new object[]
|
||||||
|
{
|
||||||
|
new Version("1.0.0.0"),
|
||||||
|
},
|
||||||
|
new object[]
|
||||||
|
{
|
||||||
|
new Version("0.1.0.0"),
|
||||||
|
},
|
||||||
|
new object[]
|
||||||
|
{
|
||||||
|
new Version("0.0.1.0"),
|
||||||
|
},
|
||||||
|
new object[]
|
||||||
|
{
|
||||||
|
new Version(1, 0, 0, 0),
|
||||||
|
},
|
||||||
|
new object[]
|
||||||
|
{
|
||||||
|
new Version(0, 1, 0, 0),
|
||||||
|
},
|
||||||
|
new object[]
|
||||||
|
{
|
||||||
|
new Version(0, 0, 0, 1),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,135 @@
|
||||||
|
// Licensed to the .NET Foundation under one or more agreements.
|
||||||
|
// The .NET Foundation licenses this file to you under the MIT license.
|
||||||
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Microsoft.Templates.Core.Test.Helpers.FsTests.Helpers
|
||||||
|
{
|
||||||
|
[SuppressMessage("Design", "CA1063:Implement IDisposable Correctly", Justification = "Testing purposes only")]
|
||||||
|
public class FSTestsFixture : IDisposable
|
||||||
|
{
|
||||||
|
public string LogFile { get; private set; }
|
||||||
|
|
||||||
|
public CultureInfo CultureInfo { get; }
|
||||||
|
|
||||||
|
public string TestPath { get; private set; }
|
||||||
|
|
||||||
|
private string folderPath;
|
||||||
|
|
||||||
|
public FSTestsFixture()
|
||||||
|
{
|
||||||
|
CultureInfo = new CultureInfo("en-US");
|
||||||
|
TestPath = Path.Combine(Environment.CurrentDirectory, "TempTestData");
|
||||||
|
Directory.CreateDirectory(TestPath);
|
||||||
|
|
||||||
|
LogFile = Path.Combine(
|
||||||
|
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
|
||||||
|
Configuration.Current.LogFileFolderPath,
|
||||||
|
$"WTS_{Configuration.Current.Environment}_{DateTime.Now:yyyyMMdd}.log");
|
||||||
|
|
||||||
|
if (File.Exists(LogFile))
|
||||||
|
{
|
||||||
|
File.Delete(LogFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void CreateFolders(string testFolder, List<string> folderPaths)
|
||||||
|
{
|
||||||
|
var foldersWithAbsolutePath = folderPaths.Select(f => $"{testFolder}\\{f}").ToList();
|
||||||
|
foreach (string folder in foldersWithAbsolutePath)
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(folder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void CreateFiles(string testFolder, List<string> filePaths, bool isReadOnly = false)
|
||||||
|
{
|
||||||
|
var filesWithAbsolutePath = filePaths.Select(f => $"{testFolder}\\{f}").ToList();
|
||||||
|
foreach (string file in filesWithAbsolutePath)
|
||||||
|
{
|
||||||
|
using var stream = File.Create(file);
|
||||||
|
if (isReadOnly)
|
||||||
|
{
|
||||||
|
var fileInfo = new FileInfo(file)
|
||||||
|
{
|
||||||
|
IsReadOnly = isReadOnly,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public string CreateTempFolderForTest(string folderName)
|
||||||
|
{
|
||||||
|
folderPath = $"{TestPath}\\{folderName}";
|
||||||
|
Directory.CreateDirectory(folderPath);
|
||||||
|
return folderPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void DeleteTempFolderForTest(string folderPath)
|
||||||
|
{
|
||||||
|
if (Directory.Exists(folderPath))
|
||||||
|
{
|
||||||
|
foreach (var file in Directory.GetFiles(folderPath))
|
||||||
|
{
|
||||||
|
_ = new FileInfo(file)
|
||||||
|
{
|
||||||
|
IsReadOnly = false,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
Directory.Delete(folderPath, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool CheckLoggingDataIsExpected(DateTime logDate, string errorLevel, string errorMessage)
|
||||||
|
{
|
||||||
|
// Sample of Logging line: [2021-06-07 20:51:30.557]... Warning Error creating folder 'C:\...\bin\Debug\netcoreapp3.1\TestData\EnsureFolderExists\Test_EnsureFolderExists': ..... because a file or directory with the same name already exists.
|
||||||
|
var logFileLines = File.ReadAllText(LogFile);
|
||||||
|
|
||||||
|
var errorDateFormat = $"{logDate:yyyy\\-MM\\-dd}";
|
||||||
|
var errorMatchPattern = $"^\\[({errorDateFormat}.*)({errorLevel}).*({errorMessage})";
|
||||||
|
var errorRegex = new Regex(errorMatchPattern, RegexOptions.Compiled | RegexOptions.Multiline);
|
||||||
|
|
||||||
|
return errorRegex.IsMatch(logFileLines);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsErrorMessageInLogFile(DateTime logDate, string errorLevel, string errorMessage)
|
||||||
|
{
|
||||||
|
if (File.Exists(LogFile))
|
||||||
|
{
|
||||||
|
var lastModifiedWriteTime = File.GetLastWriteTime(LogFile);
|
||||||
|
|
||||||
|
var timeSinceLastEdit = logDate - lastModifiedWriteTime;
|
||||||
|
if (timeSinceLastEdit.Seconds < 30)
|
||||||
|
{
|
||||||
|
return CheckLoggingDataIsExpected(logDate, errorLevel, errorMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
[SuppressMessage("Usage", "CA1816:Dispose methods should call SuppressFinalize", Justification = "Testing purposes only")]
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
if (Directory.Exists(TestPath))
|
||||||
|
{
|
||||||
|
Directory.Delete(TestPath, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[SuppressMessage("StyleCop", "SA1402", Justification = "This class does not have implementation")]
|
||||||
|
[CollectionDefinition("Unit Test Logs")]
|
||||||
|
public class LogCollection : ICollectionFixture<FSTestsFixture>
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,67 @@
|
||||||
|
// Licensed to the .NET Foundation under one or more agreements.
|
||||||
|
// The .NET Foundation licenses this file to you under the MIT license.
|
||||||
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using Microsoft.Templates.Core.Helpers;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Microsoft.Templates.Core.Test.Helpers
|
||||||
|
{
|
||||||
|
[Trait("ExecutionSet", "Minimum")]
|
||||||
|
public class FileHelpersTests
|
||||||
|
{
|
||||||
|
[Theory]
|
||||||
|
[InlineData("")]
|
||||||
|
[InlineData(" ")]
|
||||||
|
[InlineData(" ")]
|
||||||
|
[InlineData(null)]
|
||||||
|
public void GetFileContent_EmptyFilePath_ShouldReturnEmpty(string sourceFile)
|
||||||
|
{
|
||||||
|
var actual = FileHelper.GetFileContent(sourceFile);
|
||||||
|
|
||||||
|
Assert.Empty(actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData("TestData\\TestProject")]
|
||||||
|
[InlineData("TestData\\TestProject\\TestNotExisting.csproj")]
|
||||||
|
public void GetFileContent_WrongFilePath_ShouldReturnEmpty(string file)
|
||||||
|
{
|
||||||
|
var sourceFile = Path.Combine(Environment.CurrentDirectory, file);
|
||||||
|
|
||||||
|
var actual = FileHelper.GetFileContent(sourceFile);
|
||||||
|
|
||||||
|
Assert.Empty(actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void GetFileContent_FileExists_ShouldReturnsCorrectly()
|
||||||
|
{
|
||||||
|
var sourceFile = Path.Combine(Environment.CurrentDirectory, "TestData\\TestProject\\Test.csproj");
|
||||||
|
|
||||||
|
var actual = FileHelper.GetFileContent(sourceFile);
|
||||||
|
|
||||||
|
Assert.NotEmpty(actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void GetFileContent_WithFileOpened_ShouldReturnEmpty()
|
||||||
|
{
|
||||||
|
var sourceFile = Path.Combine(Environment.CurrentDirectory, "TestData\\TestProject\\EditingTest.csproj");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using var file = File.Create(sourceFile);
|
||||||
|
var actual = FileHelper.GetFileContent(sourceFile);
|
||||||
|
|
||||||
|
Assert.Empty(actual);
|
||||||
|
file.Close();
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
File.Delete(sourceFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,103 @@
|
||||||
|
// Licensed to the .NET Foundation under one or more agreements.
|
||||||
|
// The .NET Foundation licenses this file to you under the MIT license.
|
||||||
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Threading;
|
||||||
|
using Microsoft.Templates.Core.Helpers;
|
||||||
|
using Microsoft.Templates.Core.Test.Helpers.FsTests.Helpers;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Microsoft.Templates.Core.Test.Helpers.FsTests
|
||||||
|
{
|
||||||
|
[Collection("Unit Test Logs")]
|
||||||
|
[Trait("ExecutionSet", "Minimum")]
|
||||||
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1063:Implement IDisposable Correctly", Justification = "Testing purposes only")]
|
||||||
|
public class EnsureFileEditableTests : IDisposable
|
||||||
|
{
|
||||||
|
private readonly FSTestsFixture _fixture;
|
||||||
|
private readonly string _testFolder;
|
||||||
|
|
||||||
|
private DateTime _logDate;
|
||||||
|
|
||||||
|
private const string ErrorMessage = "Cannot remove readonly protection from file";
|
||||||
|
private const string ErrorLevel = "Warning";
|
||||||
|
|
||||||
|
public EnsureFileEditableTests(FSTestsFixture fixture)
|
||||||
|
{
|
||||||
|
_fixture = fixture;
|
||||||
|
Thread.CurrentThread.CurrentUICulture = fixture.CultureInfo;
|
||||||
|
_testFolder = _fixture.CreateTempFolderForTest("EnsureFolderExists");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void EnsureFileEditable_FileIsReadOnly_ShouldChangeToReadOnly()
|
||||||
|
{
|
||||||
|
var testScenarioName = "FileIsReadOnly";
|
||||||
|
var fileToEdit = $"{_testFolder}\\{testScenarioName}";
|
||||||
|
try
|
||||||
|
{
|
||||||
|
FSTestsFixture.CreateFiles(_testFolder, new List<string> { testScenarioName }, true);
|
||||||
|
|
||||||
|
Fs.EnsureFileEditable(fileToEdit);
|
||||||
|
var newFileInfo = new FileInfo(fileToEdit);
|
||||||
|
|
||||||
|
Assert.False(newFileInfo.IsReadOnly);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_ = new FileInfo(fileToEdit)
|
||||||
|
{
|
||||||
|
IsReadOnly = false,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData("")]
|
||||||
|
[InlineData(null)]
|
||||||
|
public void EnsureFileEditable_FilePathNullOrEmpty_ShouldLogError(string filePath)
|
||||||
|
{
|
||||||
|
_logDate = DateTime.Now;
|
||||||
|
|
||||||
|
Fs.EnsureFileEditable(filePath);
|
||||||
|
|
||||||
|
Assert.True(_fixture.IsErrorMessageInLogFile(_logDate, ErrorLevel, ErrorMessage));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void EnsureFileEditable_FileDoesNotExist_ShouldLogError()
|
||||||
|
{
|
||||||
|
var testScenarioName = "FileDoesNotExist";
|
||||||
|
string filePath = $"{_testFolder}\\{testScenarioName}";
|
||||||
|
_logDate = DateTime.Now;
|
||||||
|
|
||||||
|
Fs.EnsureFileEditable(filePath);
|
||||||
|
|
||||||
|
Assert.True(_fixture.IsErrorMessageInLogFile(_logDate, ErrorLevel, ErrorMessage));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void EnsureFileEditable_FileIsNotReadOnly_ShouldNotModifyIsReadOnly()
|
||||||
|
{
|
||||||
|
var testScenarioName = "FileIsNotReadOnly";
|
||||||
|
string filePath = $"{_testFolder}\\{testScenarioName}";
|
||||||
|
FSTestsFixture.CreateFiles(_testFolder, new List<string> { testScenarioName });
|
||||||
|
|
||||||
|
var originalFileInfo = new FileInfo(filePath);
|
||||||
|
Fs.EnsureFileEditable(filePath);
|
||||||
|
var newFileInfo = new FileInfo(filePath);
|
||||||
|
|
||||||
|
Assert.False(originalFileInfo.IsReadOnly);
|
||||||
|
Assert.False(newFileInfo.IsReadOnly);
|
||||||
|
}
|
||||||
|
|
||||||
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA1816:Dispose methods should call SuppressFinalize", Justification = "Testing purposes only")]
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
FSTestsFixture.DeleteTempFolderForTest(_testFolder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,95 @@
|
||||||
|
// Licensed to the .NET Foundation under one or more agreements.
|
||||||
|
// The .NET Foundation licenses this file to you under the MIT license.
|
||||||
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Threading;
|
||||||
|
using Microsoft.Templates.Core.Helpers;
|
||||||
|
using Microsoft.Templates.Core.Test.Helpers.FsTests.Helpers;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Microsoft.Templates.Core.Test.Helpers.FsTests
|
||||||
|
{
|
||||||
|
[Collection("Unit Test Logs")]
|
||||||
|
[Trait("ExecutionSet", "Minimum")]
|
||||||
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1063:Implement IDisposable Correctly", Justification = "Testing purposes only")]
|
||||||
|
public class EnsureFolderExistsTests : IDisposable
|
||||||
|
{
|
||||||
|
private readonly FSTestsFixture _fixture;
|
||||||
|
private readonly string _testFolder;
|
||||||
|
|
||||||
|
private DateTime _logDate;
|
||||||
|
|
||||||
|
private const string ErrorMessage = "Error creating folder";
|
||||||
|
private const string ErrorLevel = "Warning";
|
||||||
|
|
||||||
|
public EnsureFolderExistsTests(FSTestsFixture fixture)
|
||||||
|
{
|
||||||
|
_fixture = fixture;
|
||||||
|
Thread.CurrentThread.CurrentUICulture = fixture.CultureInfo;
|
||||||
|
_testFolder = _fixture.CreateTempFolderForTest("EnsureFolderExists");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void EnsureFolderExists_DirectoryDoesNotExists_ShouldCreateDirectory()
|
||||||
|
{
|
||||||
|
var testScenarioName = "DirectoryDoesNotExists";
|
||||||
|
var directoryToCreate = $"{_testFolder}\\{testScenarioName}";
|
||||||
|
|
||||||
|
var directoryExistsAtStart = Directory.Exists(directoryToCreate);
|
||||||
|
var totalOriginalDirectories = Directory.GetParent(directoryToCreate).GetDirectories().Length;
|
||||||
|
|
||||||
|
Fs.EnsureFolderExists(directoryToCreate);
|
||||||
|
|
||||||
|
var totalNewDirectories = Directory.GetParent(directoryToCreate).GetDirectories().Length;
|
||||||
|
|
||||||
|
Assert.True(totalNewDirectories > totalOriginalDirectories);
|
||||||
|
Assert.False(directoryExistsAtStart);
|
||||||
|
Assert.True(Directory.Exists(directoryToCreate));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void EnsureFolderExists_DirectoryAlreadyExists_ShouldNotCreateDirectory()
|
||||||
|
{
|
||||||
|
var testScenarioName = "DirectoryAlreadyExists";
|
||||||
|
var directoryToCreate = $"{_testFolder}\\{testScenarioName}";
|
||||||
|
|
||||||
|
FSTestsFixture.CreateFolders(_testFolder, new List<string> { testScenarioName });
|
||||||
|
|
||||||
|
var directoryExistsAtStart = Directory.Exists(directoryToCreate);
|
||||||
|
var totalOriginalDirectories = Directory.GetParent(directoryToCreate).GetDirectories().Length;
|
||||||
|
|
||||||
|
Fs.EnsureFolderExists(directoryToCreate);
|
||||||
|
|
||||||
|
var totalNewDirectories = Directory.GetParent(directoryToCreate).GetDirectories().Length;
|
||||||
|
|
||||||
|
Assert.True(totalOriginalDirectories == totalNewDirectories);
|
||||||
|
Assert.True(directoryExistsAtStart);
|
||||||
|
Assert.True(Directory.Exists(directoryToCreate));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void EnsureFolderExists_ErrorCreatingDirectory_ShouldLogException()
|
||||||
|
{
|
||||||
|
// To force an error creating a Directory
|
||||||
|
// we create a file with the name of the folder that we want to create
|
||||||
|
var testScenarioName = "ErrorCreatingDirectory";
|
||||||
|
var wrongDirectoryToCreate = $"{testScenarioName}\\{testScenarioName}.cs";
|
||||||
|
FSTestsFixture.CreateFolders(_testFolder, new List<string> { testScenarioName });
|
||||||
|
FSTestsFixture.CreateFiles(_testFolder, new List<string> { wrongDirectoryToCreate });
|
||||||
|
|
||||||
|
_logDate = DateTime.Now;
|
||||||
|
Fs.EnsureFolderExists($"{_testFolder}\\{wrongDirectoryToCreate}");
|
||||||
|
|
||||||
|
Assert.True(_fixture.IsErrorMessageInLogFile(_logDate, ErrorLevel, ErrorMessage));
|
||||||
|
}
|
||||||
|
|
||||||
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA1816:Dispose methods should call SuppressFinalize", Justification = "Testing purposes only")]
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
FSTestsFixture.DeleteTempFolderForTest(_testFolder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
// Licensed to the .NET Foundation under one or more agreements.
|
||||||
|
// The .NET Foundation licenses this file to you under the MIT license.
|
||||||
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using Microsoft.Templates.Core.Helpers;
|
||||||
|
using Microsoft.Templates.Core.Test.Helpers.FsTests.Helpers;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Microsoft.Templates.Core.Test.Helpers.FsTests
|
||||||
|
{
|
||||||
|
[Collection("Unit Test Logs")]
|
||||||
|
[Trait("ExecutionSet", "Minimum")]
|
||||||
|
public class GetExistingFolderNamesTests
|
||||||
|
{
|
||||||
|
private readonly FSTestsFixture _fixture;
|
||||||
|
private readonly string _testFolder;
|
||||||
|
|
||||||
|
public GetExistingFolderNamesTests(FSTestsFixture fixture)
|
||||||
|
{
|
||||||
|
_fixture = fixture;
|
||||||
|
_testFolder = _fixture.CreateTempFolderForTest("GetExistingFolderNames");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void GetExistingFolderNames_RootExists_ShouldReturnAllExpectedFolderNamesInAlphabeticalOrder()
|
||||||
|
{
|
||||||
|
var testScenarioName = "RootExists";
|
||||||
|
var directoryExists = $"{_testFolder}\\{testScenarioName}";
|
||||||
|
|
||||||
|
FSTestsFixture.CreateFolders(_testFolder, new List<string> { testScenarioName, $"{testScenarioName}\\One", $"{testScenarioName}\\Two", $"{testScenarioName}\\Three" });
|
||||||
|
|
||||||
|
var expected = new List<string>() { "One", "Three", "Two" };
|
||||||
|
|
||||||
|
var actual = Fs.GetExistingFolderNames(directoryExists);
|
||||||
|
|
||||||
|
Assert.Equal(3, actual.Count());
|
||||||
|
Assert.Equal(expected, actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData("")]
|
||||||
|
[InlineData(null)]
|
||||||
|
public void GetExistingFolderNames_RootDirectoryEmptyOrNull_ShouldReturnEmptyList(string rootDirectory)
|
||||||
|
{
|
||||||
|
var actual = Fs.GetExistingFolderNames(rootDirectory);
|
||||||
|
|
||||||
|
Assert.Empty(actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void GetExistingFolderNames_RootDirectoryDoesNotExist_ShouldReturnEmptyList()
|
||||||
|
{
|
||||||
|
var testScenarioName = "RootDirectoryDoesNotExist";
|
||||||
|
var directoryDoesNotExist = $"{_testFolder}\\{testScenarioName}";
|
||||||
|
|
||||||
|
var actual = Fs.GetExistingFolderNames(directoryDoesNotExist);
|
||||||
|
|
||||||
|
Assert.Empty(actual);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,177 @@
|
||||||
|
// Licensed to the .NET Foundation under one or more agreements.
|
||||||
|
// The .NET Foundation licenses this file to you under the MIT license.
|
||||||
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Threading;
|
||||||
|
using Microsoft.Templates.Core.Helpers;
|
||||||
|
using Microsoft.Templates.Core.Test.Helpers.FsTests.Helpers;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Microsoft.Templates.Core.Test.Helpers.FsTests
|
||||||
|
{
|
||||||
|
[Collection("Unit Test Logs")]
|
||||||
|
[Trait("ExecutionSet", "Minimum")]
|
||||||
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1063:Implement IDisposable Correctly", Justification = "Testing purposes only")]
|
||||||
|
public class SafeCopyFileTests : IDisposable
|
||||||
|
{
|
||||||
|
private readonly FSTestsFixture _fixture;
|
||||||
|
private readonly string _testFolder;
|
||||||
|
private readonly string _sourceFile;
|
||||||
|
|
||||||
|
private DateTime _logDate;
|
||||||
|
|
||||||
|
private const string ErrorMessage = "can't be copied to";
|
||||||
|
private const string ErrorLevel = "Warning";
|
||||||
|
|
||||||
|
public SafeCopyFileTests(FSTestsFixture fixture)
|
||||||
|
{
|
||||||
|
_fixture = fixture;
|
||||||
|
Thread.CurrentThread.CurrentUICulture = fixture.CultureInfo;
|
||||||
|
|
||||||
|
_sourceFile = $"TestData\\TestProject\\Test.csproj";
|
||||||
|
_testFolder = _fixture.CreateTempFolderForTest("SafeCopyFile");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void SafeCopyFile_DestinationDirectoryDoesNotExist_ShouldCreateDirectory()
|
||||||
|
{
|
||||||
|
var testScenarioName = "DestinationDirectoryDoesNotExist";
|
||||||
|
var directoryToCreate = $"{_testFolder}\\{testScenarioName}";
|
||||||
|
var directoryExistsAtStart = Directory.Exists(directoryToCreate);
|
||||||
|
var totalOriginalDirectories = Directory.GetParent(directoryToCreate).GetDirectories().Length;
|
||||||
|
|
||||||
|
Fs.SafeCopyFile(_sourceFile, directoryToCreate, true);
|
||||||
|
|
||||||
|
var totalNewDirectories = Directory.GetParent(directoryToCreate).GetDirectories().Length;
|
||||||
|
|
||||||
|
var directoryHasBeenCreated = totalNewDirectories > totalOriginalDirectories;
|
||||||
|
|
||||||
|
Assert.False(directoryExistsAtStart);
|
||||||
|
Assert.True(directoryHasBeenCreated);
|
||||||
|
Assert.True(Directory.Exists(directoryToCreate));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void SafeCopyFile_FileDoesNotExist_ShouldCreateNewFileWhileCopying()
|
||||||
|
{
|
||||||
|
var testScenarioName = "FileDoesNotExist";
|
||||||
|
var directoryToCreate = $"{_testFolder}\\{testScenarioName}";
|
||||||
|
FSTestsFixture.CreateFolders(_testFolder, new List<string>() { testScenarioName });
|
||||||
|
var expectedDestinationFile = Path.Combine(directoryToCreate, Path.GetFileName(_sourceFile));
|
||||||
|
|
||||||
|
var fileExistsAtStart = File.Exists(expectedDestinationFile);
|
||||||
|
var totalOriginalFiles = Directory.GetFiles(directoryToCreate).Length;
|
||||||
|
|
||||||
|
Fs.SafeCopyFile(_sourceFile, directoryToCreate, true);
|
||||||
|
|
||||||
|
var totalNewFiles = Directory.GetFiles(directoryToCreate).Length;
|
||||||
|
|
||||||
|
var fileHasBeenCreated = totalNewFiles > totalOriginalFiles;
|
||||||
|
Assert.False(fileExistsAtStart);
|
||||||
|
Assert.True(fileHasBeenCreated);
|
||||||
|
Assert.True(File.Exists(expectedDestinationFile));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void SafeCopyFile_DestinationDirectoryAlreadyExists_ShouldNotCreateDirectory()
|
||||||
|
{
|
||||||
|
var testScenarioName = "DestinationDirectoryAlreadyExists";
|
||||||
|
var directoryToCopyFile = $"{_testFolder}\\{testScenarioName}";
|
||||||
|
FSTestsFixture.CreateFolders(_testFolder, new List<string>() { testScenarioName });
|
||||||
|
var totalOriginalDirectories = Directory.GetParent(directoryToCopyFile).GetDirectories().Length;
|
||||||
|
|
||||||
|
Fs.SafeCopyFile(_sourceFile, directoryToCopyFile, true);
|
||||||
|
|
||||||
|
var totalNewDirectories = Directory.GetParent(directoryToCopyFile).GetDirectories().Length;
|
||||||
|
|
||||||
|
var noDirectoryHasBeenCreated = totalOriginalDirectories == totalNewDirectories;
|
||||||
|
|
||||||
|
Assert.True(noDirectoryHasBeenCreated);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void SafeCopyFile_FileAlreadyExists_ShouldNotCreateNewFileWhileCopying()
|
||||||
|
{
|
||||||
|
var testScenarioName = "FileAlreadyExists";
|
||||||
|
var directoryToCopyFile = $"{_testFolder}\\{testScenarioName}";
|
||||||
|
var totalOriginalFiles = Directory.GetParent(directoryToCopyFile).GetFiles().Length;
|
||||||
|
var expectedDestinationFile = Path.Combine(directoryToCopyFile, Path.GetFileName(_sourceFile));
|
||||||
|
var fileInfo = new FileInfo(expectedDestinationFile);
|
||||||
|
var originalLastModificationTime = fileInfo.LastWriteTime;
|
||||||
|
|
||||||
|
Fs.SafeCopyFile(_sourceFile, directoryToCopyFile, true);
|
||||||
|
|
||||||
|
var totalNewFiles = Directory.GetParent(directoryToCopyFile).GetFiles().Length;
|
||||||
|
|
||||||
|
var noFileHasBeenCreated = totalNewFiles == totalOriginalFiles;
|
||||||
|
fileInfo = new FileInfo(expectedDestinationFile);
|
||||||
|
var updatedLastModificationTime = fileInfo.LastWriteTime;
|
||||||
|
|
||||||
|
Assert.True(noFileHasBeenCreated);
|
||||||
|
Assert.NotEqual(originalLastModificationTime, updatedLastModificationTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData(null)]
|
||||||
|
[InlineData("")]
|
||||||
|
public void SafeCopyFile_SourceFileNullOrEmpty_ShouldLogException(string filePath)
|
||||||
|
{
|
||||||
|
var testScenarioName = "SourceFileNullOrEmpty";
|
||||||
|
var directoryToCopyFile = $"{_testFolder}\\{testScenarioName}";
|
||||||
|
_logDate = DateTime.Now;
|
||||||
|
|
||||||
|
Fs.SafeCopyFile(filePath, directoryToCopyFile, true);
|
||||||
|
|
||||||
|
Assert.True(_fixture.IsErrorMessageInLogFile(_logDate, ErrorLevel, ErrorMessage));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void SafeCopyFile_CouldNotFindFile_ShouldLogException()
|
||||||
|
{
|
||||||
|
var testScenarioName = "CouldNotFindFile";
|
||||||
|
var directoryToCopyFile = $"{_testFolder}\\{testScenarioName}";
|
||||||
|
var sourceFileDoesNotExist = $"{_testFolder}\\FileDoNotExists.csproj";
|
||||||
|
_logDate = DateTime.Now;
|
||||||
|
|
||||||
|
Fs.SafeCopyFile(sourceFileDoesNotExist, directoryToCopyFile, true);
|
||||||
|
|
||||||
|
Assert.True(_fixture.IsErrorMessageInLogFile(_logDate, ErrorLevel, ErrorMessage));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void SafeCopyFile_AccessToPathDenied_ShouldLogException()
|
||||||
|
{
|
||||||
|
// to force an exception while trying to copy a file. File without permissions instead of valid folder
|
||||||
|
var testScenarioName = "AccessToPathDenied";
|
||||||
|
var directoryToCopyFile = $"{_testFolder}\\{testScenarioName}";
|
||||||
|
var sourceFileDoesNotHavePermissions = Environment.CurrentDirectory;
|
||||||
|
_logDate = DateTime.Now;
|
||||||
|
|
||||||
|
Fs.SafeCopyFile(sourceFileDoesNotHavePermissions, directoryToCopyFile, true);
|
||||||
|
|
||||||
|
Assert.True(_fixture.IsErrorMessageInLogFile(_logDate, ErrorLevel, ErrorMessage));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void SafeCopyFile_AccessToPathDenied_OvewriteFalse_ShouldLogException()
|
||||||
|
{
|
||||||
|
var testScenarioName = "AccessToPathDenied_OvewriteFalse";
|
||||||
|
var directoryToCopyFile = $"{_testFolder}\\{testScenarioName}";
|
||||||
|
var sourceFileDoesNotHavePermissions = Environment.CurrentDirectory;
|
||||||
|
_logDate = DateTime.Now;
|
||||||
|
|
||||||
|
Fs.SafeCopyFile(sourceFileDoesNotHavePermissions, directoryToCopyFile, false);
|
||||||
|
|
||||||
|
Assert.True(_fixture.IsErrorMessageInLogFile(_logDate, ErrorLevel, ErrorMessage));
|
||||||
|
}
|
||||||
|
|
||||||
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA1816:Dispose methods should call SuppressFinalize", Justification = "Testing purposes only")]
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
FSTestsFixture.DeleteTempFolderForTest(_testFolder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,70 @@
|
||||||
|
// Licensed to the .NET Foundation under one or more agreements.
|
||||||
|
// The .NET Foundation licenses this file to you under the MIT license.
|
||||||
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using Microsoft.Templates.Core.Helpers;
|
||||||
|
using Microsoft.Templates.Core.Test.Helpers.FsTests.Helpers;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Microsoft.Templates.Core.Test.Helpers.FsTests
|
||||||
|
{
|
||||||
|
[Collection("Unit Test Logs")]
|
||||||
|
[Trait("ExecutionSet", "Minimum")]
|
||||||
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1063:Implement IDisposable Correctly", Justification = "Testing purposes only")]
|
||||||
|
public class SafeDeleteDirectoryTests : IDisposable
|
||||||
|
{
|
||||||
|
private readonly FSTestsFixture _fixture;
|
||||||
|
private readonly string _testFolder;
|
||||||
|
|
||||||
|
public SafeDeleteDirectoryTests(FSTestsFixture fixture)
|
||||||
|
{
|
||||||
|
_fixture = fixture;
|
||||||
|
_testFolder = _fixture.CreateTempFolderForTest("SafeDeleteDirectory");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void SafeDeleteDirectory_DirectoryExists_ShouldDeleteDirectory()
|
||||||
|
{
|
||||||
|
var testScenarioName = "DirectoryExists";
|
||||||
|
var directoryToCreate = $"{_testFolder}\\{testScenarioName}";
|
||||||
|
|
||||||
|
FSTestsFixture.CreateFolders(_testFolder, new List<string>() { testScenarioName });
|
||||||
|
|
||||||
|
var totalOriginalDirectories = Directory.GetParent(directoryToCreate).GetDirectories().Length;
|
||||||
|
|
||||||
|
Fs.SafeDeleteDirectory(directoryToCreate, false);
|
||||||
|
|
||||||
|
var totalNewDirectories = Directory.GetParent(directoryToCreate).GetDirectories().Length;
|
||||||
|
|
||||||
|
var directoryHasBeenDeleted = totalNewDirectories < totalOriginalDirectories;
|
||||||
|
|
||||||
|
Assert.True(directoryHasBeenDeleted);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData("")]
|
||||||
|
[InlineData(null)]
|
||||||
|
public void SafeDeleteDirectory_DirectoryPathIsNullOrEmpty_ShouldNotThrowException(string rootDir)
|
||||||
|
{
|
||||||
|
Fs.SafeDeleteDirectory(rootDir);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void SafeDeleteDirectory_WrongFolder_ShouldNotThrowException()
|
||||||
|
{
|
||||||
|
var testScenarioName = "WrongFolder";
|
||||||
|
var wrongDirectoryToDelete = $"{_testFolder}\\{testScenarioName}";
|
||||||
|
|
||||||
|
Fs.SafeDeleteDirectory(wrongDirectoryToDelete, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA1816:Dispose methods should call SuppressFinalize", Justification = "Testing purposes only")]
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
FSTestsFixture.DeleteTempFolderForTest(_testFolder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,89 @@
|
||||||
|
// Licensed to the .NET Foundation under one or more agreements.
|
||||||
|
// The .NET Foundation licenses this file to you under the MIT license.
|
||||||
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Threading;
|
||||||
|
using Microsoft.Templates.Core.Helpers;
|
||||||
|
using Microsoft.Templates.Core.Test.Helpers.FsTests.Helpers;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Microsoft.Templates.Core.Test.Helpers.FsTests
|
||||||
|
{
|
||||||
|
[Collection("Unit Test Logs")]
|
||||||
|
[Trait("ExecutionSet", "Minimum")]
|
||||||
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1063:Implement IDisposable Correctly", Justification = "Testing purposes only")]
|
||||||
|
public class SafeDeleteFileTests : IDisposable
|
||||||
|
{
|
||||||
|
private readonly FSTestsFixture _fixture;
|
||||||
|
private readonly string _testFolder;
|
||||||
|
|
||||||
|
private DateTime _logDate;
|
||||||
|
private const string ErrorMessage = "can't be deleted";
|
||||||
|
private const string ErrorLevel = "Warning";
|
||||||
|
|
||||||
|
public SafeDeleteFileTests(FSTestsFixture fixture)
|
||||||
|
{
|
||||||
|
_fixture = fixture;
|
||||||
|
Thread.CurrentThread.CurrentUICulture = fixture.CultureInfo;
|
||||||
|
_testFolder = _fixture.CreateTempFolderForTest("SafeDeleteFile");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void SafeDeleteFile_ExistingFile_ShouldHaveDeletedFile()
|
||||||
|
{
|
||||||
|
var testScenarioName = "ExistingFile";
|
||||||
|
var directoryToCreate = $"{_testFolder}\\{testScenarioName}";
|
||||||
|
var fileToDelete = $"{directoryToCreate}\\{testScenarioName}.csproj";
|
||||||
|
|
||||||
|
FSTestsFixture.CreateFolders(_testFolder, new List<string>() { testScenarioName });
|
||||||
|
FSTestsFixture.CreateFiles(_testFolder, new List<string>() { $"{testScenarioName}\\{testScenarioName}.csproj" });
|
||||||
|
var fileExistsBefore = File.Exists(fileToDelete);
|
||||||
|
Fs.SafeDeleteFile(fileToDelete);
|
||||||
|
|
||||||
|
Assert.True(fileExistsBefore);
|
||||||
|
Assert.False(File.Exists(fileToDelete));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData("")]
|
||||||
|
[InlineData(null)]
|
||||||
|
public void SafeDeleteFile_PathNotFound_ShouldNotThrowException(string filePath)
|
||||||
|
{
|
||||||
|
Fs.SafeDeleteFile(filePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void SafeDeleteFile_NoPermissions_ShouldHandleException()
|
||||||
|
{
|
||||||
|
var testScenarioName = "NoPermissions";
|
||||||
|
var directoryToCreate = $"{_testFolder}\\{testScenarioName}";
|
||||||
|
var fileToDelete = $"{directoryToCreate}\\{testScenarioName}.csproj";
|
||||||
|
try
|
||||||
|
{
|
||||||
|
FSTestsFixture.CreateFolders(_testFolder, new List<string>() { testScenarioName });
|
||||||
|
FSTestsFixture.CreateFiles(_testFolder, new List<string>() { $"{testScenarioName}\\{testScenarioName}.csproj" }, true);
|
||||||
|
|
||||||
|
_logDate = DateTime.Now;
|
||||||
|
Fs.SafeDeleteFile(fileToDelete);
|
||||||
|
|
||||||
|
Assert.True(_fixture.IsErrorMessageInLogFile(_logDate, ErrorLevel, ErrorMessage));
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_ = new FileInfo(fileToDelete)
|
||||||
|
{
|
||||||
|
IsReadOnly = false,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA1816:Dispose methods should call SuppressFinalize", Justification = "Testing purposes only")]
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
FSTestsFixture.DeleteTempFolderForTest(_testFolder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,159 @@
|
||||||
|
// Licensed to the .NET Foundation under one or more agreements.
|
||||||
|
// The .NET Foundation licenses this file to you under the MIT license.
|
||||||
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Threading;
|
||||||
|
using Microsoft.Templates.Core.Helpers;
|
||||||
|
using Microsoft.Templates.Core.Test.Helpers.FsTests.Helpers;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Microsoft.Templates.Core.Test.Helpers.FsTests
|
||||||
|
{
|
||||||
|
[Collection("Unit Test Logs")]
|
||||||
|
[Trait("ExecutionSet", "Minimum")]
|
||||||
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1063:Implement IDisposable Correctly", Justification = "Testing purposes only")]
|
||||||
|
public class SafeMoveFileTests : IDisposable
|
||||||
|
{
|
||||||
|
private readonly FSTestsFixture _fixture;
|
||||||
|
private readonly string _testFolder;
|
||||||
|
|
||||||
|
private DateTime _logDate;
|
||||||
|
|
||||||
|
private const string ErrorMessage = "can't be moved to";
|
||||||
|
private const string ErrorLevel = "Warning";
|
||||||
|
|
||||||
|
public SafeMoveFileTests(FSTestsFixture fixture)
|
||||||
|
{
|
||||||
|
_fixture = fixture;
|
||||||
|
Thread.CurrentThread.CurrentUICulture = fixture.CultureInfo;
|
||||||
|
_testFolder = _fixture.CreateTempFolderForTest("SafeMoveFile");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void SafeMoveFile_ValidData_ShouldMove()
|
||||||
|
{
|
||||||
|
var testScenarioName = "ValidData";
|
||||||
|
var originalFile = $"{_testFolder}\\{testScenarioName}_Original.cs";
|
||||||
|
var movedFile = $"{_testFolder}\\{testScenarioName}_Moved.cs";
|
||||||
|
|
||||||
|
FSTestsFixture.CreateFiles(_testFolder, new List<string> { Path.GetFileName(originalFile) });
|
||||||
|
|
||||||
|
var originFolderTotalFiles = Directory.GetFiles(_testFolder).Length;
|
||||||
|
|
||||||
|
Fs.SafeMoveFile(originalFile, movedFile);
|
||||||
|
|
||||||
|
var destinationFolderTotalFiles = Directory.GetFiles(_testFolder).Length;
|
||||||
|
|
||||||
|
Assert.True(originFolderTotalFiles == destinationFolderTotalFiles);
|
||||||
|
Assert.False(File.Exists(originalFile));
|
||||||
|
Assert.True(File.Exists(movedFile));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData("", "anything")]
|
||||||
|
[InlineData(null, "anything")]
|
||||||
|
public void SafeMoveFile_OriginFileDoesNotExist_JustReturns(string filePath, string newfilePath)
|
||||||
|
{
|
||||||
|
Fs.SafeMoveFile(filePath, newfilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void SafeMoveFile_DestFileExists_Overwrite_MovesFileSuccessfully()
|
||||||
|
{
|
||||||
|
var testScenarioName = "DestFileExists_Overwrite";
|
||||||
|
var originalFile = $"{_testFolder}\\{testScenarioName}_Original.cs";
|
||||||
|
var movedFile = $"{_testFolder}\\{testScenarioName}_Moved.cs";
|
||||||
|
|
||||||
|
FSTestsFixture.CreateFiles(_testFolder, new List<string> { Path.GetFileName(originalFile), Path.GetFileName(movedFile) });
|
||||||
|
|
||||||
|
var originFolderTotalFiles = Directory.GetFiles(_testFolder).Length;
|
||||||
|
|
||||||
|
Fs.SafeMoveFile(originalFile, movedFile);
|
||||||
|
|
||||||
|
var destinationFolderTotalFiles = Directory.GetFiles(_testFolder).Length;
|
||||||
|
|
||||||
|
Assert.True(originFolderTotalFiles > destinationFolderTotalFiles);
|
||||||
|
Assert.False(File.Exists(originalFile));
|
||||||
|
Assert.True(File.Exists(movedFile));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void SafeMoveFile_DestFileExists_NoOverwrite_JustReturns()
|
||||||
|
{
|
||||||
|
var testScenarioName = "DestFileExists_NoOverwrite";
|
||||||
|
var originalFile = $"{_testFolder}\\{testScenarioName}_Original.cs";
|
||||||
|
var movedFile = $"{_testFolder}\\{testScenarioName}_Moved.cs";
|
||||||
|
|
||||||
|
FSTestsFixture.CreateFiles(_testFolder, new List<string> { Path.GetFileName(originalFile), Path.GetFileName(movedFile) });
|
||||||
|
|
||||||
|
var originFolderTotalFiles = Directory.GetFiles(_testFolder).Length;
|
||||||
|
|
||||||
|
Fs.SafeMoveFile(originalFile, movedFile, false);
|
||||||
|
|
||||||
|
var destinationFolderTotalFiles = Directory.GetFiles(_testFolder).Length;
|
||||||
|
|
||||||
|
Assert.True(originFolderTotalFiles == destinationFolderTotalFiles);
|
||||||
|
Assert.True(File.Exists(originalFile));
|
||||||
|
Assert.True(File.Exists(movedFile));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void SafeMoveFile_DestFileExists_Overwrite_NoPermissions_ShouldLogException()
|
||||||
|
{
|
||||||
|
var testScenarioName = "DestFileExists_Overwrite_NoPermissions";
|
||||||
|
var originalFile = $"{_testFolder}\\{testScenarioName}_Original.cs";
|
||||||
|
var movedFile = $"{_testFolder}\\{testScenarioName}_Moved.cs";
|
||||||
|
|
||||||
|
FSTestsFixture.CreateFiles(_testFolder, new List<string> { Path.GetFileName(originalFile), Path.GetFileName(movedFile) }, true);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_logDate = DateTime.Now;
|
||||||
|
Fs.SafeMoveFile(originalFile, movedFile);
|
||||||
|
|
||||||
|
Assert.True(_fixture.IsErrorMessageInLogFile(_logDate, ErrorLevel, ErrorMessage));
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_ = new FileInfo(movedFile)
|
||||||
|
{
|
||||||
|
IsReadOnly = false,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void SafeMoveFile_DestFileExists_Overwrite_NoPermissions_NoWarnOnFailure_ShouldNotLogException()
|
||||||
|
{
|
||||||
|
var testScenarioName = "DestFileExists_Overwrite_NoPermissions_NoWarnOnFailure";
|
||||||
|
var originalFile = $"{_testFolder}\\{testScenarioName}_Original.cs";
|
||||||
|
var movedFile = $"{_testFolder}\\{testScenarioName}_Moved.cs";
|
||||||
|
|
||||||
|
FSTestsFixture.CreateFiles(_testFolder, new List<string> { Path.GetFileName(originalFile), Path.GetFileName(movedFile) }, true);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_logDate = DateTime.Now;
|
||||||
|
Fs.SafeMoveFile(originalFile, movedFile, true, false);
|
||||||
|
|
||||||
|
Assert.False(_fixture.IsErrorMessageInLogFile(_logDate, ErrorLevel, $"{Path.GetFileName(movedFile)} {ErrorMessage}"));
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_ = new FileInfo(movedFile)
|
||||||
|
{
|
||||||
|
IsReadOnly = false,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA1816:Dispose methods should call SuppressFinalize", Justification = "Testing purposes only")]
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
FSTestsFixture.DeleteTempFolderForTest(_testFolder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,125 @@
|
||||||
|
// Licensed to the .NET Foundation under one or more agreements.
|
||||||
|
// The .NET Foundation licenses this file to you under the MIT license.
|
||||||
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Threading;
|
||||||
|
using Microsoft.Templates.Core.Helpers;
|
||||||
|
using Microsoft.Templates.Core.Test.Helpers.FsTests.Helpers;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Microsoft.Templates.Core.Test.Helpers.FsTests
|
||||||
|
{
|
||||||
|
[Collection("Unit Test Logs")]
|
||||||
|
[Trait("ExecutionSet", "Minimum")]
|
||||||
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1063:Implement IDisposable Correctly", Justification = "Testing purposes only")]
|
||||||
|
public class SafeRenameDirectoryTests : IDisposable
|
||||||
|
{
|
||||||
|
private readonly FSTestsFixture _fixture;
|
||||||
|
private readonly string _testFolder;
|
||||||
|
|
||||||
|
private DateTime _logDate;
|
||||||
|
|
||||||
|
private const string ErrorMessage = "can't be renamed";
|
||||||
|
private const string ErrorLevel = "Warning";
|
||||||
|
|
||||||
|
public SafeRenameDirectoryTests(FSTestsFixture fixture)
|
||||||
|
{
|
||||||
|
_fixture = fixture;
|
||||||
|
Thread.CurrentThread.CurrentUICulture = fixture.CultureInfo;
|
||||||
|
_testFolder = _fixture.CreateTempFolderForTest("SafeRenameDirectory");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void SafeRenameDirectory_ValidData_ShouldMoveDirectory()
|
||||||
|
{
|
||||||
|
var testScenarioName = "ValidData";
|
||||||
|
var originalDirectory = $"{_testFolder}\\{testScenarioName}_Original";
|
||||||
|
var renamedDirectory = $"{_testFolder}\\{testScenarioName}_Renamed";
|
||||||
|
|
||||||
|
FSTestsFixture.CreateFolders(_testFolder, new List<string> { $"{testScenarioName}_Original" });
|
||||||
|
|
||||||
|
var totalOriginalDirectories = Directory.GetParent(originalDirectory).GetDirectories().Length;
|
||||||
|
|
||||||
|
Fs.SafeRenameDirectory(originalDirectory, renamedDirectory);
|
||||||
|
|
||||||
|
var totalNewDirectories = Directory.GetParent(originalDirectory).GetDirectories().Length;
|
||||||
|
|
||||||
|
var sameNumberOfDirectories = totalNewDirectories == totalOriginalDirectories;
|
||||||
|
Assert.True(sameNumberOfDirectories);
|
||||||
|
var oldDirectoryHasBeenMovedToNewDirectory = Directory.Exists(renamedDirectory) && !Directory.Exists(originalDirectory);
|
||||||
|
Assert.True(oldDirectoryHasBeenMovedToNewDirectory);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData("", "anything")]
|
||||||
|
[InlineData(null, "anything")]
|
||||||
|
public void SafeRenameDirectory_DoesNotExist_ShouldNotThrowException(string rootDir, string newRootDir)
|
||||||
|
{
|
||||||
|
Fs.SafeRenameDirectory(rootDir, newRootDir);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void SafeRenameDirectory_DirectoryAlreadyExists_ShouldLogException()
|
||||||
|
{
|
||||||
|
var testScenarioName = "ValidData";
|
||||||
|
var originalDirectory = $"{_testFolder}\\{testScenarioName}_Original";
|
||||||
|
var renamedDirectory = $"{_testFolder}\\{testScenarioName}_Renamed";
|
||||||
|
|
||||||
|
FSTestsFixture.CreateFolders(_testFolder, new List<string> { $"{testScenarioName}_Original", $"{testScenarioName}_Renamed" });
|
||||||
|
|
||||||
|
var totalOriginalDirectories = Directory.GetParent(originalDirectory).GetDirectories().Length;
|
||||||
|
|
||||||
|
_logDate = DateTime.Now;
|
||||||
|
Fs.SafeRenameDirectory(originalDirectory, renamedDirectory);
|
||||||
|
|
||||||
|
var totalNewDirectories = Directory.GetParent(originalDirectory).GetDirectories().Length;
|
||||||
|
|
||||||
|
var sameNumberOfDirectories = totalNewDirectories == totalOriginalDirectories;
|
||||||
|
Assert.True(sameNumberOfDirectories);
|
||||||
|
Assert.True(_fixture.IsErrorMessageInLogFile(_logDate, ErrorLevel, $"{testScenarioName}_Original {ErrorMessage}"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void SafeRenameDirectory_WrongDestinationFolder_ShouldLogException()
|
||||||
|
{
|
||||||
|
// to throw the exception we create a file with the same name we try to create the new directory
|
||||||
|
var testScenarioName = "WrongDestinationFolder";
|
||||||
|
var originalDirectory = $"{_testFolder}\\{testScenarioName}_Original";
|
||||||
|
var wrongDirectory = $"{_testFolder}\\{testScenarioName}_WrongFolder.cs";
|
||||||
|
|
||||||
|
FSTestsFixture.CreateFolders(_testFolder, new List<string> { $"{testScenarioName}_Original", $"{testScenarioName}_Renamed" });
|
||||||
|
FSTestsFixture.CreateFiles(_testFolder, new List<string> { $"{testScenarioName}_WrongFolder.cs" });
|
||||||
|
|
||||||
|
_logDate = DateTime.Now;
|
||||||
|
Fs.SafeRenameDirectory(originalDirectory, wrongDirectory);
|
||||||
|
|
||||||
|
Assert.True(_fixture.IsErrorMessageInLogFile(_logDate, ErrorLevel, $"{testScenarioName}_Original {ErrorMessage}"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void SafeRenameDirectory_WrongDestinationFolder_WarnOnFailureFalse_ShouldNotLogError()
|
||||||
|
{
|
||||||
|
// to throw the exception we create a file with the same name we try to create the new directory
|
||||||
|
var testScenarioName = "WrongDestinationFolder_WarnOnFailureFalse";
|
||||||
|
var originalDirectory = $"{_testFolder}\\{testScenarioName}_Original";
|
||||||
|
var wrongDirectory = $"{_testFolder}\\{testScenarioName}_WrongFolder.cs";
|
||||||
|
|
||||||
|
FSTestsFixture.CreateFolders(_testFolder, new List<string> { $"{testScenarioName}_Original", $"{testScenarioName}_Renamed" });
|
||||||
|
FSTestsFixture.CreateFiles(_testFolder, new List<string> { $"{testScenarioName}_WrongFolder.cs" });
|
||||||
|
|
||||||
|
_logDate = DateTime.Now;
|
||||||
|
Fs.SafeRenameDirectory(originalDirectory, wrongDirectory, false);
|
||||||
|
|
||||||
|
Assert.False(_fixture.IsErrorMessageInLogFile(_logDate, ErrorLevel, $"{testScenarioName}_Original {ErrorMessage}"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA1816:Dispose methods should call SuppressFinalize", Justification = "Testing purposes only")]
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
FSTestsFixture.DeleteTempFolderForTest(_testFolder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -127,7 +127,7 @@ namespace WtsPackagingTool
|
||||||
destinationDir = System.Environment.CurrentDirectory;
|
destinationDir = System.Environment.CurrentDirectory;
|
||||||
}
|
}
|
||||||
|
|
||||||
Fs.EnsureFolder(destinationDir);
|
Fs.EnsureFolderExists(destinationDir);
|
||||||
|
|
||||||
output.WriteCommandHeader($"Extracting {inputFile} to {destinationDir}...");
|
output.WriteCommandHeader($"Extracting {inputFile} to {destinationDir}...");
|
||||||
await templatePackage.ExtractAsync(inputFile, destinationDir).ConfigureAwait(false);
|
await templatePackage.ExtractAsync(inputFile, destinationDir).ConfigureAwait(false);
|
||||||
|
@ -306,7 +306,7 @@ namespace WtsPackagingTool
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Fs.EnsureFolder(resultDir);
|
Fs.EnsureFolderExists(resultDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
return resultDir;
|
return resultDir;
|
||||||
|
|
|
@ -106,7 +106,7 @@ namespace WtsPackagingTool
|
||||||
|
|
||||||
if (package != null)
|
if (package != null)
|
||||||
{
|
{
|
||||||
Fs.EnsureFolder(options.Destination);
|
Fs.EnsureFolderExists(options.Destination);
|
||||||
|
|
||||||
var result = RemoteSource.DownloadCdnElement(Environments.CdnUrls[options.Env], package.Name, options.Destination);
|
var result = RemoteSource.DownloadCdnElement(Environments.CdnUrls[options.Env], package.Name, options.Destination);
|
||||||
output.WriteLine();
|
output.WriteLine();
|
||||||
|
|
Загрузка…
Ссылка в новой задаче