diff --git a/Winium/Winium.Mobile.Connectivity/Deployer.cs b/Winium/Winium.Mobile.Connectivity/Deployer.cs index e1dd84c..906a91f 100644 --- a/Winium/Winium.Mobile.Connectivity/Deployer.cs +++ b/Winium/Winium.Mobile.Connectivity/Deployer.cs @@ -113,7 +113,7 @@ public void ReceiveFile(string isoStoreRoot, string sourceDeviceFilePath, string .ReceiveFile(sourceDeviceFilePath, targetDesktopFilePath, true); } - public void SendFiles(Dictionary files) + public void SendFiles(List> files) { if (files == null || !files.Any()) { @@ -123,14 +123,8 @@ public void SendFiles(Dictionary files) var isolatedStore = this.RemoteApplication.GetIsolatedStore("Local"); foreach (var file in files) { - var phoneDirectoryName = Path.GetDirectoryName(file.Value); - var phoneFileName = Path.GetFileName(file.Value); - if (string.IsNullOrEmpty(phoneFileName)) - { - phoneFileName = Path.GetFileName(file.Key); - } - - isolatedStore.SendFile(file.Key, Path.Combine(phoneDirectoryName, phoneFileName), true); + Logger.Debug("Sending file \"{0}\" to \"{1}\"", file.Key, file.Value); + isolatedStore.SendFile(file.Key, file.Value, true); } } diff --git a/Winium/Winium.Mobile.Connectivity/IDeployer.cs b/Winium/Winium.Mobile.Connectivity/IDeployer.cs index f893f98..cc593e3 100644 --- a/Winium/Winium.Mobile.Connectivity/IDeployer.cs +++ b/Winium/Winium.Mobile.Connectivity/IDeployer.cs @@ -24,7 +24,7 @@ public interface IDeployer void ReceiveFile(string isoStoreRoot, string sourceDeviceFilePath, string targetDesktopFilePath); - void SendFiles(Dictionary files); + void SendFiles(List> files); void Terminate(); diff --git a/Winium/Winium.StoreApps.Driver.Tests/FileListExpanderTests.cs b/Winium/Winium.StoreApps.Driver.Tests/FileListExpanderTests.cs new file mode 100644 index 0000000..ed49d60 --- /dev/null +++ b/Winium/Winium.StoreApps.Driver.Tests/FileListExpanderTests.cs @@ -0,0 +1,88 @@ +namespace Winium.StoreApps.Driver.Tests +{ + #region + + using System.Collections.Generic; + using System.IO.Abstractions.TestingHelpers; + using System.Linq; + + using NUnit.Framework; + + using Winium.StoreApps.Driver.CommandHelpers; + + #endregion + + [TestFixture] + public class FileExpanderTests + { + #region Fields + + private FilesCapabilityExpander expander; + + #endregion + + #region Public Methods and Operators + + [SetUp] + public void BeforeTest() + { + var fileSystem = + new MockFileSystem( + new Dictionary + { + { @"c:\root.txt", new MockFileData(string.Empty) }, + { @"c:\demo\nested1.txt", new MockFileData(string.Empty) }, + { @"c:\demo\nested2.txt", new MockFileData(string.Empty) }, + { @"c:\demo\subfolder\file.txt", new MockFileData(string.Empty) }, + }); + + this.expander = new FilesCapabilityExpander(fileSystem); + } + + [Test] + public void TestFileExpanderFileToDirectory() + { + var d = new Dictionary { { @"c:\root.txt", "downloads/" } }; + var rv = this.expander.ExpandFiles(d); + Assert.AreEqual("downloads\\root.txt", rv.First().Value); + } + + [Test] + public void TestFileExpanderFileToFile() + { + var d = new Dictionary { { @"c:\root.txt", "downloads/new.txt" } }; + var rv = this.expander.ExpandFiles(d); + Assert.AreEqual("downloads\\new.txt", rv.First().Value); + } + + [Test] + public void TestFileExpanderDirectoryToDirectory() + { + var d = new Dictionary { { @"c:\demo/", "downloads" } }; + var rv = this.expander.ExpandFiles(d); + var expected = new List + { + @"downloads\nested1.txt", + @"downloads\nested2.txt", + @"downloads\subfolder\file.txt", + }; + CollectionAssert.AreEqual(expected, rv.Select(x => x.Value)); + } + + [Test] + public void TestFileExpanderDirectoryToRootDirectory() + { + var d = new Dictionary { { @"c:\demo/", string.Empty } }; + var rv = this.expander.ExpandFiles(d); + var expected = new List + { + @"nested1.txt", + @"nested2.txt", + @"subfolder\file.txt", + }; + CollectionAssert.AreEqual(expected, rv.Select(x => x.Value)); + } + + #endregion + } +} diff --git a/Winium/Winium.StoreApps.Driver.Tests/Properties/AssemblyInfo.cs b/Winium/Winium.StoreApps.Driver.Tests/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..b339529 --- /dev/null +++ b/Winium/Winium.StoreApps.Driver.Tests/Properties/AssemblyInfo.cs @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Winium.StoreApps.Driver.Tests")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Winium.StoreApps.Driver.Tests")] +[assembly: AssemblyCopyright("Copyright © 2015")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("0c036ea5-8c76-4638-832d-9ced3a0ed57c")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Winium/Winium.StoreApps.Driver.Tests/Winium.StoreApps.Driver.Tests.csproj b/Winium/Winium.StoreApps.Driver.Tests/Winium.StoreApps.Driver.Tests.csproj new file mode 100644 index 0000000..a8c3376 --- /dev/null +++ b/Winium/Winium.StoreApps.Driver.Tests/Winium.StoreApps.Driver.Tests.csproj @@ -0,0 +1,111 @@ + + + + Debug + AnyCPU + {07168ED9-C12A-43F5-898F-84AB113A9441} + Library + Properties + Winium.StoreApps.Driver.Tests + Winium.StoreApps.Driver.Tests + v4.5.1 + 512 + {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 10.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages + False + UnitTest + ..\ + true + + + true + bin\x86\Debug\ + DEBUG;TRACE + full + x86 + prompt + MinimumRecommendedRules.ruleset + + + bin\x86\Release\ + TRACE + true + pdbonly + x86 + prompt + MinimumRecommendedRules.ruleset + + + + ..\packages\NUnit.2.6.4\lib\nunit.framework.dll + + + + ..\packages\System.IO.Abstractions.2.0.0.120\lib\net40\System.IO.Abstractions.dll + + + ..\packages\System.IO.Abstractions.TestingHelpers.2.0.0.120\lib\net40\System.IO.Abstractions.TestingHelpers.dll + + + + + + + + + + + + + + + + + + + + + {B6BE579B-B008-45B2-9740-12F0E6223661} + Winium.StoreApps.Driver + + + + + + + + + + False + + + False + + + False + + + False + + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + \ No newline at end of file diff --git a/Winium/Winium.StoreApps.Driver.Tests/packages.config b/Winium/Winium.StoreApps.Driver.Tests/packages.config new file mode 100644 index 0000000..014043c --- /dev/null +++ b/Winium/Winium.StoreApps.Driver.Tests/packages.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Winium/Winium.StoreApps.Driver/Automator/Automator.cs b/Winium/Winium.StoreApps.Driver/Automator/Automator.cs index b08674a..63e8d73 100644 --- a/Winium/Winium.StoreApps.Driver/Automator/Automator.cs +++ b/Winium/Winium.StoreApps.Driver/Automator/Automator.cs @@ -7,6 +7,7 @@ using System.Diagnostics; using System.Drawing; using System.IO; + using System.Linq; using System.Threading; using Newtonsoft.Json; @@ -16,6 +17,7 @@ using Winium.Mobile.Connectivity.Emulator; using Winium.StoreApps.Common; using Winium.StoreApps.Common.Exceptions; + using Winium.StoreApps.Driver.CommandHelpers; using Winium.StoreApps.Logging; #endregion @@ -168,7 +170,8 @@ private void InitializeApplication(string appPath) else { this.Deployer.Install(appPath, this.ActualCapabilities.Dependencies); - this.Deployer.SendFiles(this.ActualCapabilities.Files); + var expandedFiles = new FilesCapabilityExpander().ExpandFiles(this.ActualCapabilities.Files).ToList(); + this.Deployer.SendFiles(expandedFiles); } } diff --git a/Winium/Winium.StoreApps.Driver/CommandHelpers/FilesCapabilityExpander.cs b/Winium/Winium.StoreApps.Driver/CommandHelpers/FilesCapabilityExpander.cs new file mode 100644 index 0000000..307dccc --- /dev/null +++ b/Winium/Winium.StoreApps.Driver/CommandHelpers/FilesCapabilityExpander.cs @@ -0,0 +1,114 @@ +namespace Winium.StoreApps.Driver.CommandHelpers +{ + #region + + using System; + using System.Collections.Generic; + using System.IO; + using System.IO.Abstractions; + + #endregion + + public class FilesCapabilityExpander + { + #region Fields + + private readonly IFileSystem fileSystem; + + #endregion + + #region Constructors and Destructors + + public FilesCapabilityExpander(IFileSystem fileSystem = null) + { + if (fileSystem == null) + { + fileSystem = new FileSystem(); + } + + this.fileSystem = fileSystem; + } + + #endregion + + #region Public Methods and Operators + + public IEnumerable> ExpandFiles(Dictionary files) + { + foreach (var item in files) + { + var source = NormalizePathSeparators(item.Key); + var destination = NormalizePathSeparators(item.Value); + if (this.fileSystem.Directory.Exists(source)) + { + var directoryInfo = this.fileSystem.DirectoryInfo.FromDirectoryName(source); + foreach (var expandedItem in this.ExpandDirectory(directoryInfo, destination)) + { + yield return expandedItem; + } + } + else if (this.fileSystem.File.Exists(item.Key)) + { + var fileInfo = this.fileSystem.FileInfo.FromFileName(source); + var expanded = this.ExpandFile(fileInfo, destination); + yield return expanded; + } + else + { + throw new IOException(string.Format("No such file or directory {0}", item.Key)); + } + } + } + + #endregion + + #region Methods + + private static string MakeRelative(FileInfoBase file, DirectoryInfoBase referenceDirectory) + { + var referencePath = NormalizePathSeparators(referenceDirectory.FullName); + referencePath = referencePath.TrimEnd(Path.DirectorySeparatorChar) + Path.DirectorySeparatorChar; + var filePath = file.FullName; + var fileUri = new Uri(filePath); + var referenceUri = new Uri(referencePath); + var relativePath = referenceUri.MakeRelativeUri(fileUri).ToString(); + return NormalizePathSeparators(relativePath); + } + + private static string NormalizePathSeparators(string path) + { + return path.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar); + } + + private IEnumerable> ExpandDirectory( + DirectoryInfoBase directoryInfo, + string phonePath) + { + foreach (var item in directoryInfo.GetFiles("*", SearchOption.AllDirectories)) + { + var relativePath = MakeRelative(item, directoryInfo); + yield return + new KeyValuePair( + item.FullName, + this.fileSystem.Path.Combine(phonePath, relativePath)); + } + } + + private KeyValuePair ExpandFile(FileInfoBase fileInfo, string phonePath) + { + var phoneDirectoryName = this.fileSystem.Path.GetDirectoryName(phonePath); + var phoneFileName = this.fileSystem.Path.GetFileName(phonePath); + + if (string.IsNullOrEmpty(phoneFileName)) + { + phoneFileName = fileInfo.Name; + } + + var fullName = this.fileSystem.Path.Combine(phoneDirectoryName, phoneFileName); + var expandedFile = new KeyValuePair(fileInfo.FullName, fullName); + return expandedFile; + } + + #endregion + } +} diff --git a/Winium/Winium.StoreApps.Driver/Winium.StoreApps.Driver.csproj b/Winium/Winium.StoreApps.Driver/Winium.StoreApps.Driver.csproj index 72c5a3b..d847afa 100644 --- a/Winium/Winium.StoreApps.Driver/Winium.StoreApps.Driver.csproj +++ b/Winium/Winium.StoreApps.Driver/Winium.StoreApps.Driver.csproj @@ -46,6 +46,9 @@ + + ..\packages\System.IO.Abstractions.2.0.0.120\lib\net40\System.IO.Abstractions.dll + @@ -81,6 +84,7 @@ + diff --git a/Winium/Winium.StoreApps.Driver/packages.config b/Winium/Winium.StoreApps.Driver/packages.config index db12488..b6fd4bc 100644 --- a/Winium/Winium.StoreApps.Driver/packages.config +++ b/Winium/Winium.StoreApps.Driver/packages.config @@ -2,4 +2,5 @@ + \ No newline at end of file diff --git a/Winium/Winium.sln b/Winium/Winium.sln index 2584332..534ab6a 100644 --- a/Winium/Winium.sln +++ b/Winium/Winium.sln @@ -41,6 +41,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Winium.StoreApps.Logging", EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Phone.Tools.Deploy.Patched", "Microsoft.Phone.Tools.Deploy.Patched\Microsoft.Phone.Tools.Deploy.Patched.csproj", "{13B4DF5C-E542-4A7A-8F00-929D423B522C}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Winium.StoreApps.Driver.Tests", "Winium.StoreApps.Driver.Tests\Winium.StoreApps.Driver.Tests.csproj", "{07168ED9-C12A-43F5-898F-84AB113A9441}" +EndProject Global GlobalSection(SharedMSBuildProjectFiles) = preSolution TestApp\TestApp.Shared\TestApp.Shared.projitems*{10a0b15d-ca68-4a4f-83bc-639a62b5ef1e}*SharedItemsImports = 4 @@ -93,6 +95,9 @@ Global {13B4DF5C-E542-4A7A-8F00-929D423B522C}.Debug|Any CPU.Build.0 = Debug|x86 {13B4DF5C-E542-4A7A-8F00-929D423B522C}.Release|Any CPU.ActiveCfg = Release|x86 {13B4DF5C-E542-4A7A-8F00-929D423B522C}.Release|Any CPU.Build.0 = Release|x86 + {07168ED9-C12A-43F5-898F-84AB113A9441}.Debug|Any CPU.ActiveCfg = Debug|x86 + {07168ED9-C12A-43F5-898F-84AB113A9441}.Debug|Any CPU.Build.0 = Debug|x86 + {07168ED9-C12A-43F5-898F-84AB113A9441}.Release|Any CPU.ActiveCfg = Release|x86 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE