mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-03 09:46:54 +02:00
Merge ImageResizer into master (#1469)
* Import Image Resizer for Windows * getting code analysis and stylecop hooked in * upgrading to 4.7.2 * adding copyright * getting stuff to work headers and trailing commas adding braces updated encoder * Revert "getting stuff to work" This reverts commit5310866120. * update to .net 4.7.2 * access modifier * zero errors * Fixed unit tests not running issue * Fixed ImageResizer.Test stylecop warning * Formatted ShellExtensions project with clang-format * Fixed annotation warnings * Suppressed 6031 and 26812 warnings for specific lines * Shifting ImageResizer projects to PowerToys solution (#1054) * Shifted ImageResizer projects to PowerToys solution: Builds, all tests pass, ImageResizer C# project works independently * Deleted extra files * Deleted nuget config file and fixed code analysis paths * Convert ImageResizer to a PowerToy (#1073) * Updated vcxproj file with common project references and cpp version flags * Added module template code to dllmain and updated headers for successful build * Removed unnecessary include * Added dll to runner and add fixes to show up in PT Settings * Added settings file * Added support for enabling/disabling based on PowerRename codebase * Fixed missing braces * Fixed call_custom_action * Add ImageResizer to msi installer (dev/imageResizer) (#1094) * Updated vcxproj file with common project references and cpp version flags * Added module template code to dllmain and updated headers for successful build * Removed unnecessary include * Added dll to runner and add fixes to show up in PT Settings * Added settings file * Added support for enabling/disabling based on PowerRename codebase * Fixed solution file configurations * Removed Any CPU from ImageResizer csprojs * Renamed registry writing and removed build time registry addition * Added ImageResizer installation details to msi * Fixed comment on conditions to close explorer.exe * Sync dev/imageResizer with master (#1105) * tweaking language * adjusting elevated permission verbiage to match Windows * npm audit fix to update stuff * slight bump for fabric ui * Remove unwanted files (#1037) Add temp build files to gitignore * Ensure previous search and replace texts are evaluated and updated in the UI at startup (#1043) Ensure stored settings get evaluated after initial enumeration There was a bug where the list view was not getting updated with the results of the search and replace on launch when we are using a stored search or replace text from a previous session. * adding fancy zone opacity setting, enhancement #631 (#1008) * adding fancy zone opacity setting, enhancement #631 * applying zone opacity setting to all zones during zone selection * changing opacity setting to percentage * runner: show message box when restarting with different elevation fails (#1061) Also make the message box appear on top of the settings window. * Fix misaligned display of zones in layout priview and grid editor (#1010) Fix misaligned display of zones in layout preview and grid editor * MSIX: Extract MSIX building functionality from msix_reinstall.ps1 to a separate script (#1068) * MSIX: label PowerToys as Preview (#1090) * MSIX: Code sign msixbundle (#1093) * Update to MSIX README.md (#1095) * Update README.md few adjustments * Update README.md * Update README.md * adding in privacy statement, removing About in dialog (#1087) * adding in privacy statement, removing About in dialog * added Preview * Revert "Fix misaligned display of zones in layout priview and grid editor (#1010)" (#1097) This reverts commitd03690cffd. * Fix reversed order of zones in layout (#1071) * Shifted three functions to common (#1101) Co-authored-by: Clint Rutkas <clint@rutkas.com> Co-authored-by: Enrico Giordani <enricogior@users.noreply.github.com> Co-authored-by: Chris Davis <chrisdavis@outlook.com> Co-authored-by: Yosef Durr <yodurr@microsoft.com> Co-authored-by: Bartosz Sosnowski <bzoz@users.noreply.github.com> Co-authored-by: vldmr11080 <57061786+vldmr11080@users.noreply.github.com> Co-authored-by: yuyoyuppe <yuyoyuppe@users.noreply.github.com> * Revert "Sync dev/imageResizer with master (#1105)" This reverts commitdb7f15541f. * Added icon to Resize pictures context menu entry (dev/imageResizer) (#1113) * Updated vcxproj file with common project references and cpp version flags * Added module template code to dllmain and updated headers for successful build * Removed unnecessary include * Added dll to runner and add fixes to show up in PT Settings * Added settings file * Added support for enabling/disabling based on PowerRename codebase * Fixed solution file configurations * Removed Any CPU from ImageResizer csprojs * Renamed registry writing and removed build time registry addition * Added ImageResizer installation details to msi * Shifted to MII, TODO: Fix position * Incorporated ImageResizer Icon in context menu entry * Fixed typo * Merged with dev/imageResizer * Renamed Advanced Options to Settings and removed About tab (dev/imageResizer) (#1123) * Removed about tab, renamed advanced opt to settings, changed assembly info * Restored Resource designer file * Reverted changes on AssemblyInfo * MSI: Fix ImageResizer menu item position (dev/imageResizer) (#1114) * Updated vcxproj file with common project references and cpp version flags * Added module template code to dllmain and updated headers for successful build * Removed unnecessary include * Added dll to runner and add fixes to show up in PT Settings * Added settings file * Added support for enabling/disabling based on PowerRename codebase * Fixed solution file configurations * Removed Any CPU from ImageResizer csprojs * Renamed registry writing and removed build time registry addition * Added ImageResizer installation details to msi * Shifted to MII, TODO: Fix position * Incorporated ImageResizer Icon in context menu entry * Changed registry entries to SystemFileAssociations and added index changes in InsertMenuItem * Fixed extra newline * Fixed merge conflict * Refactor ImageResizer code base naming to match PowerRename (#1121) * Created empty README file * Renamed dll project * Removed ShellExtensions references in src * Fixed ImageResizerUI assembly name and added changes to MSI * added the helper functions * localized dllmain powerrename * localized powerRenameExt * localized the settings file * built the proj * Modified resourceIDs for strings in the table * added common as a reference project * Removed get_res_string_wchar and used the get_resource_string() function instead which returns a wstring typecast into wchar* * Added new lines to the end of the file * Removed string resources from the settings.cpp file * rebuilt project PowerRename * moved app name to constructor to init only once * updated formatting of common.cpp * reverting formatting of files * Removed some IDs from resource file. Changed SHIFT to Shift * Localizing C# Project of FancyZones (FancyZonesEditor) (#199) (#1122) * removed hardcoded strings from CanvasEditorWindow.xaml * removed hardcoded strings from GridEditorWindow.xaml * loc * Localized MainWindow * reverting MainWindow.xaml as it is not rendering the window as expected * Changed the resource settings from internal to public * the culture is set based on the culture of the system UI set in the system settings * Removed the french resource files used for testing * Localized canvasWindow and mainwindow * Removed setting the UI culture explicitly as it would be implicitly set to the culture of system UI * Removed redundant header file * Localize the Shortcut guide PowerToy (#199) (#1126) * Localized shortcut_guide.cpp * localized overlay_window.cpp * formatting changes * Localize overlay window * removed the README link from the set of localized resources * Typo: changed upper to lower * Localize C++ Projects of FancyZones (#1130) * localized dllmain.cpp of fancyzones project * localized FancyZones.cpp * format fancyzones.rc file * Moved SuperFancyZones back to being a string instead of having it in the resource file as it is the window class name * reverted changes for window name * Formatted fancyzones rc file * Align zone dimensions from layout preview with those from grid editor (#1115) * MSIX: add a dedicated .rc for UWPUI which joins both UI and DLL .rc's (#1139) * Runner: fix restarting with same elevation (#1133) * MSIX: reinstall script uses bundle instead of .msi to be able to reinstall in all cases * Telemetry: add WebView init failure errors * Settings: initialize COM security to allow communication between elevated Settings and WebView * Common: implement on_scope_exit helper and typed_storage * Changes for #1140 and #569 (#1152) * MSIX build instructions adjustmnet (#1170) * MSIX: hide the "Run at Startup" option if running as packaged * MSIX: update identity name and publisher (#1176) * Runner: fix startup task state setting for MSIX (#1181) * Add ImageResizer to MSIX installer and make the code MSIX-compatible (#1219) * Removed ImageResizer.exe location registry key * Added working resize pictures to MSIX context menu without icon * Fixed missing icon on MSIX build * Added comments * Changed to single context handler entry * Made changes as per PR comments * Localize ImageResizer (#1261) * Removed hardcoded strings * Added resource dlls to MSIX installer * Save ImageResizer settings in JSON format (#1258) * Combined settings files * Added JSON settings functionality in PowerToys format with thread safety * Reverting changes to csproj file * Removed settings.settings and designer file and added target sdk tools to fix warning * Added NewtonSoft Json package * Added 3 tests * Added propertychanged test * Removed unused libraries * Removed additional allocation statements in test * Added comments on test * Added one-time setup code * Added Newtonsoft.Json.dll to MSI and MSIX installer * Fixed copyright header * Fixed folder location in MSIX * Renamed jsonMutex to _jsonMutex * Fixed line endings * Created private setup functions and added Arrange, Act, Assert comments * Created private setup functions and added Arrange, Act, Assert comments * Suppressed copyright warning on AppFixture and enabled treat warnings as errors * Added comments on Reload/AppFixture and added constructor andispose * Added telemetry to ImageResizer Shell Extension code (dev/imageResizer) (#1272) * Added telemetry to C++ ImageResizerExt * Added Register and unregister calls * Changed default enable setting * Set startup location to center of the screen (ImageResizer) (#1452) * Added ImageResizer resources.dlls to the MSI installer (#1448) * Implemented fix for foreground issue for ImageResizer (#1434) * Fixed conflict in installer README.md file * Fixed conflict in bundle.js * Auto-generate AssemblyInfo in ImageResizer (#1467) * Updated assembly info * Added auto-generation of AssemblyInfo.cs * Fixed minor issues * Remove the License file since Notice.md have been added * Fix errors due to resolving merge conflicts Co-authored-by: Brice Lambson <brice@bricelam.net> Co-authored-by: Clint Rutkas <clint@rutkas.com> Co-authored-by: Arjun Balgovind <arbalgov@microsoft.com> Co-authored-by: Enrico Giordani <enricogior@users.noreply.github.com> Co-authored-by: Chris Davis <chrisdavis@outlook.com> Co-authored-by: Yosef Durr <yodurr@microsoft.com> Co-authored-by: Bartosz Sosnowski <bzoz@users.noreply.github.com> Co-authored-by: vldmr11080 <57061786+vldmr11080@users.noreply.github.com> Co-authored-by: yuyoyuppe <yuyoyuppe@users.noreply.github.com> Co-authored-by: Alekhya Kommuru <alkommur@microsoft.com> Co-authored-by: Alekhya <reddykalekhya@gmail.com> Co-authored-by: yuyoyuppe <a.yuyoyuppe@gmail.com> Co-authored-by: Udit Singh <udsing@microsoft.com>
This commit is contained in:
6
src/modules/imageresizer/tests/App.config
Normal file
6
src/modules/imageresizer/tests/App.config
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2"/>
|
||||
</startup>
|
||||
</configuration>
|
||||
115
src/modules/imageresizer/tests/ImageResizerUITest.csproj
Normal file
115
src/modules/imageresizer/tests/ImageResizerUITest.csproj
Normal file
@@ -0,0 +1,115 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">x64</Platform>
|
||||
<ProjectGuid>{E0CC7526-D85E-43AC-844F-D5DF0D2F5AB8}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>ImageResizer</RootNamespace>
|
||||
<AssemblyName>ImageResizer.Test</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<TargetFrameworkProfile>
|
||||
</TargetFrameworkProfile>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>$(SolutionDir)$(Platform)\$(Configuration)</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
<CodeAnalysisRuleSet>..\..\..\codeAnalysis\Rules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>$(SolutionDir)$(Platform)\$(Configuration)</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
<CodeAnalysisRuleSet>..\..\..\codeAnalysis\Rules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="PresentationCore" />
|
||||
<Reference Include="System" />
|
||||
<Reference Include="WindowsBase" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\ui\ImageResizerUI.csproj">
|
||||
<Project>{2be46397-4dfa-414c-9bd4-41e4bbf8cb34}</Project>
|
||||
<Name>ImageResizerUI</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AdditionalFiles Include="..\..\..\codeAnalysis\StyleCop.json">
|
||||
<Link>StyleCop.json</Link>
|
||||
</AdditionalFiles>
|
||||
<None Include="App.config">
|
||||
<SubType>Designer</SubType>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="..\codeAnalysis\GlobalSuppressions.cs">
|
||||
<Link>GlobalSuppressions.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="Models\CustomSizeTests.cs" />
|
||||
<Compile Include="Models\ResizeSizeTests.cs" />
|
||||
<Compile Include="Models\ResizeBatchTests.cs" />
|
||||
<Compile Include="Models\ResizeOperationTests.cs" />
|
||||
<Compile Include="Properties\AppFixture.cs" />
|
||||
<Compile Include="Properties\SettingsTests.cs" />
|
||||
<Compile Include="Test\AssertEx.cs" />
|
||||
<Compile Include="Test\BitmapSourceExtensions.cs" />
|
||||
<Compile Include="Test\TestDirectory.cs" />
|
||||
<Compile Include="Views\TimeRemainingConverterTests.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Test.gif">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Test.ico">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Test.jpg">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Test.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="TestPortrait.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Moq">
|
||||
<Version>4.13.1</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="StyleCop.Analyzers">
|
||||
<Version>1.1.118</Version>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="System.ValueTuple">
|
||||
<Version>4.5.0</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="xunit">
|
||||
<Version>2.4.1</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="xunit.runner.visualstudio">
|
||||
<Version>2.4.1</Version>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
||||
22
src/modules/imageresizer/tests/Models/CustomSizeTests.cs
Normal file
22
src/modules/imageresizer/tests/Models/CustomSizeTests.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
// Copyright (c) Brice Lambson
|
||||
// The Brice Lambson licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information. Code forked from Brice Lambson's https://github.com/bricelam/ImageResizer/
|
||||
|
||||
using ImageResizer.Properties;
|
||||
using Xunit;
|
||||
|
||||
namespace ImageResizer.Models
|
||||
{
|
||||
public class CustomSizeTests
|
||||
{
|
||||
[Fact]
|
||||
public void Name_works()
|
||||
{
|
||||
var size = new CustomSize();
|
||||
|
||||
size.Name = "Ignored";
|
||||
|
||||
Assert.Equal(Resources.Input_Custom, size.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
108
src/modules/imageresizer/tests/Models/ResizeBatchTests.cs
Normal file
108
src/modules/imageresizer/tests/Models/ResizeBatchTests.cs
Normal file
@@ -0,0 +1,108 @@
|
||||
// Copyright (c) Brice Lambson
|
||||
// The Brice Lambson licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information. Code forked from Brice Lambson's https://github.com/bricelam/ImageResizer/
|
||||
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using Moq;
|
||||
using Moq.Protected;
|
||||
using Xunit;
|
||||
|
||||
namespace ImageResizer.Models
|
||||
{
|
||||
public class ResizeBatchTests
|
||||
{
|
||||
private static readonly string EOL = Environment.NewLine;
|
||||
|
||||
[Fact]
|
||||
public void FromCommandLine_works()
|
||||
{
|
||||
var standardInput =
|
||||
"Image1.jpg" + EOL +
|
||||
"Image2.jpg";
|
||||
var args = new[]
|
||||
{
|
||||
"/d", "OutputDir",
|
||||
"Image3.jpg",
|
||||
};
|
||||
|
||||
var result = ResizeBatch.FromCommandLine(
|
||||
new StringReader(standardInput),
|
||||
args);
|
||||
|
||||
Assert.Equal(new List<string> { "Image1.jpg", "Image2.jpg", "Image3.jpg" }, result.Files);
|
||||
|
||||
Assert.Equal("OutputDir", result.DestinationDirectory);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Process_executes_in_parallel()
|
||||
{
|
||||
var batch = CreateBatch(_ => Thread.Sleep(50));
|
||||
batch.Files.AddRange(
|
||||
Enumerable.Range(0, Environment.ProcessorCount)
|
||||
.Select(i => "Image" + i + ".jpg"));
|
||||
|
||||
var stopwatch = Stopwatch.StartNew();
|
||||
batch.Process(CancellationToken.None, (_, __) => { });
|
||||
stopwatch.Stop();
|
||||
|
||||
Assert.InRange(stopwatch.ElapsedMilliseconds, 50, 99);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Process_aggregates_errors()
|
||||
{
|
||||
var batch = CreateBatch(file => throw new Exception("Error: " + file));
|
||||
batch.Files.Add("Image1.jpg");
|
||||
batch.Files.Add("Image2.jpg");
|
||||
|
||||
var errors = batch.Process(CancellationToken.None, (_, __) => { }).ToList();
|
||||
|
||||
Assert.Equal(2, errors.Count);
|
||||
|
||||
var errorFiles = new List<string>();
|
||||
|
||||
foreach (var error in errors)
|
||||
{
|
||||
errorFiles.Add(error.File);
|
||||
Assert.Equal("Error: " + error.File, error.Error);
|
||||
}
|
||||
|
||||
foreach (var file in batch.Files)
|
||||
{
|
||||
Assert.Contains(file, errorFiles);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Process_reports_progress()
|
||||
{
|
||||
var batch = CreateBatch(_ => { });
|
||||
batch.Files.Add("Image1.jpg");
|
||||
batch.Files.Add("Image2.jpg");
|
||||
var calls = new ConcurrentBag<(int i, double count)>();
|
||||
|
||||
batch.Process(
|
||||
CancellationToken.None,
|
||||
(i, count) => calls.Add((i, count)));
|
||||
|
||||
Assert.Equal(2, calls.Count);
|
||||
Assert.Contains(calls, c => c.i == 1 && c.count == 2);
|
||||
Assert.Contains(calls, c => c.i == 2 && c.count == 2);
|
||||
}
|
||||
|
||||
private static ResizeBatch CreateBatch(Action<string> executeAction)
|
||||
{
|
||||
var mock = new Mock<ResizeBatch> { CallBase = true };
|
||||
mock.Protected().Setup("Execute", ItExpr.IsAny<string>()).Callback(executeAction);
|
||||
|
||||
return mock.Object;
|
||||
}
|
||||
}
|
||||
}
|
||||
453
src/modules/imageresizer/tests/Models/ResizeOperationTests.cs
Normal file
453
src/modules/imageresizer/tests/Models/ResizeOperationTests.cs
Normal file
@@ -0,0 +1,453 @@
|
||||
// Copyright (c) Brice Lambson
|
||||
// The Brice Lambson licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information. Code forked from Brice Lambson's https://github.com/bricelam/ImageResizer/
|
||||
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.IO;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using ImageResizer.Properties;
|
||||
using ImageResizer.Test;
|
||||
using Xunit;
|
||||
|
||||
namespace ImageResizer.Models
|
||||
{
|
||||
public class ResizeOperationTests : IDisposable
|
||||
{
|
||||
private readonly TestDirectory _directory = new TestDirectory();
|
||||
|
||||
[Fact]
|
||||
public void Execute_copies_frame_metadata()
|
||||
{
|
||||
var operation = new ResizeOperation("Test.jpg", _directory, Settings());
|
||||
|
||||
operation.Execute();
|
||||
|
||||
AssertEx.Image(
|
||||
_directory.File(),
|
||||
image => Assert.Equal("Test", ((BitmapMetadata)image.Frames[0].Metadata).Comment));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Execute_keeps_date_modified()
|
||||
{
|
||||
var operation = new ResizeOperation("Test.png", _directory, Settings(s => s.KeepDateModified = true));
|
||||
|
||||
operation.Execute();
|
||||
|
||||
Assert.Equal(File.GetLastWriteTimeUtc("Test.png"), File.GetLastWriteTimeUtc(_directory.File()));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Execute_keeps_date_modified_when_replacing_originals()
|
||||
{
|
||||
var path = Path.Combine(_directory, "Test.png");
|
||||
File.Copy("Test.png", path);
|
||||
|
||||
var originalDateModified = File.GetLastWriteTimeUtc(path);
|
||||
|
||||
var operation = new ResizeOperation(
|
||||
path,
|
||||
null,
|
||||
Settings(
|
||||
s =>
|
||||
{
|
||||
s.KeepDateModified = true;
|
||||
s.Replace = true;
|
||||
}));
|
||||
|
||||
operation.Execute();
|
||||
|
||||
Assert.Equal(originalDateModified, File.GetLastWriteTimeUtc(_directory.File()));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Execute_replaces_originals()
|
||||
{
|
||||
var path = Path.Combine(_directory, "Test.png");
|
||||
File.Copy("Test.png", path);
|
||||
|
||||
var operation = new ResizeOperation(path, null, Settings(s => s.Replace = true));
|
||||
|
||||
operation.Execute();
|
||||
|
||||
AssertEx.Image(_directory.File(), image => Assert.Equal(96, image.Frames[0].PixelWidth));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Execute_transforms_each_frame()
|
||||
{
|
||||
var operation = new ResizeOperation("Test.gif", _directory, Settings());
|
||||
|
||||
operation.Execute();
|
||||
|
||||
AssertEx.Image(
|
||||
_directory.File(),
|
||||
image =>
|
||||
{
|
||||
Assert.Equal(2, image.Frames.Count);
|
||||
AssertEx.All(image.Frames, frame => Assert.Equal(96, frame.PixelWidth));
|
||||
});
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Execute_uses_fallback_encoder()
|
||||
{
|
||||
var operation = new ResizeOperation(
|
||||
"Test.ico",
|
||||
_directory,
|
||||
Settings(s => s.FallbackEncoder = new PngBitmapEncoder().CodecInfo.ContainerFormat));
|
||||
|
||||
operation.Execute();
|
||||
|
||||
Assert.Contains("Test (Test).png", _directory.FileNames);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Transform_ignores_orientation_when_landscape_to_portrait()
|
||||
{
|
||||
var operation = new ResizeOperation(
|
||||
"Test.png",
|
||||
_directory,
|
||||
Settings(
|
||||
x =>
|
||||
{
|
||||
x.IgnoreOrientation = true;
|
||||
x.SelectedSize.Width = 96;
|
||||
x.SelectedSize.Height = 192;
|
||||
}));
|
||||
|
||||
operation.Execute();
|
||||
|
||||
AssertEx.Image(
|
||||
_directory.File(),
|
||||
image =>
|
||||
{
|
||||
Assert.Equal(192, image.Frames[0].PixelWidth);
|
||||
Assert.Equal(96, image.Frames[0].PixelHeight);
|
||||
});
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Transform_ignores_orientation_when_portrait_to_landscape()
|
||||
{
|
||||
var operation = new ResizeOperation(
|
||||
"TestPortrait.png",
|
||||
_directory,
|
||||
Settings(
|
||||
x =>
|
||||
{
|
||||
x.IgnoreOrientation = true;
|
||||
x.SelectedSize.Width = 192;
|
||||
x.SelectedSize.Height = 96;
|
||||
}));
|
||||
|
||||
operation.Execute();
|
||||
|
||||
AssertEx.Image(
|
||||
_directory.File(),
|
||||
image =>
|
||||
{
|
||||
Assert.Equal(96, image.Frames[0].PixelWidth);
|
||||
Assert.Equal(192, image.Frames[0].PixelHeight);
|
||||
});
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Transform_ignores_ignore_orientation_when_auto()
|
||||
{
|
||||
var operation = new ResizeOperation(
|
||||
"Test.png",
|
||||
_directory,
|
||||
Settings(
|
||||
x =>
|
||||
{
|
||||
x.IgnoreOrientation = true;
|
||||
x.SelectedSize.Width = 96;
|
||||
x.SelectedSize.Height = 0;
|
||||
}));
|
||||
|
||||
operation.Execute();
|
||||
|
||||
AssertEx.Image(
|
||||
_directory.File(),
|
||||
image =>
|
||||
{
|
||||
Assert.Equal(96, image.Frames[0].PixelWidth);
|
||||
Assert.Equal(48, image.Frames[0].PixelHeight);
|
||||
});
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Transform_ignores_ignore_orientation_when_percent()
|
||||
{
|
||||
var operation = new ResizeOperation(
|
||||
"Test.png",
|
||||
_directory,
|
||||
Settings(
|
||||
x =>
|
||||
{
|
||||
x.IgnoreOrientation = true;
|
||||
x.SelectedSize.Width = 50;
|
||||
x.SelectedSize.Height = 200;
|
||||
x.SelectedSize.Unit = ResizeUnit.Percent;
|
||||
x.SelectedSize.Fit = ResizeFit.Stretch;
|
||||
}));
|
||||
|
||||
operation.Execute();
|
||||
|
||||
AssertEx.Image(
|
||||
_directory.File(),
|
||||
image =>
|
||||
{
|
||||
Assert.Equal(96, image.Frames[0].PixelWidth);
|
||||
Assert.Equal(192, image.Frames[0].PixelHeight);
|
||||
});
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Transform_honors_shrink_only()
|
||||
{
|
||||
var operation = new ResizeOperation(
|
||||
"Test.png",
|
||||
_directory,
|
||||
Settings(
|
||||
x =>
|
||||
{
|
||||
x.ShrinkOnly = true;
|
||||
x.SelectedSize.Width = 288;
|
||||
x.SelectedSize.Height = 288;
|
||||
}));
|
||||
|
||||
operation.Execute();
|
||||
|
||||
AssertEx.Image(
|
||||
_directory.File(),
|
||||
image =>
|
||||
{
|
||||
Assert.Equal(192, image.Frames[0].PixelWidth);
|
||||
Assert.Equal(96, image.Frames[0].PixelHeight);
|
||||
});
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Transform_ignores_shrink_only_when_percent()
|
||||
{
|
||||
var operation = new ResizeOperation(
|
||||
"Test.png",
|
||||
_directory,
|
||||
Settings(
|
||||
x =>
|
||||
{
|
||||
x.ShrinkOnly = true;
|
||||
x.SelectedSize.Width = 133.3;
|
||||
x.SelectedSize.Unit = ResizeUnit.Percent;
|
||||
}));
|
||||
|
||||
operation.Execute();
|
||||
|
||||
AssertEx.Image(
|
||||
_directory.File(),
|
||||
image =>
|
||||
{
|
||||
Assert.Equal(256, image.Frames[0].PixelWidth);
|
||||
Assert.Equal(128, image.Frames[0].PixelHeight);
|
||||
});
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Transform_honors_shrink_only_when_auto_height()
|
||||
{
|
||||
var operation = new ResizeOperation(
|
||||
"Test.png",
|
||||
_directory,
|
||||
Settings(
|
||||
x =>
|
||||
{
|
||||
x.ShrinkOnly = true;
|
||||
x.SelectedSize.Width = 288;
|
||||
x.SelectedSize.Height = 0;
|
||||
}));
|
||||
|
||||
operation.Execute();
|
||||
|
||||
AssertEx.Image(
|
||||
_directory.File(),
|
||||
image => Assert.Equal(192, image.Frames[0].PixelWidth));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Transform_honors_shrink_only_when_auto_width()
|
||||
{
|
||||
var operation = new ResizeOperation(
|
||||
"Test.png",
|
||||
_directory,
|
||||
Settings(
|
||||
x =>
|
||||
{
|
||||
x.ShrinkOnly = true;
|
||||
x.SelectedSize.Width = 0;
|
||||
x.SelectedSize.Height = 288;
|
||||
}));
|
||||
|
||||
operation.Execute();
|
||||
|
||||
AssertEx.Image(
|
||||
_directory.File(),
|
||||
image => Assert.Equal(96, image.Frames[0].PixelHeight));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Transform_honors_unit()
|
||||
{
|
||||
var operation = new ResizeOperation(
|
||||
"Test.png",
|
||||
_directory,
|
||||
Settings(
|
||||
x =>
|
||||
{
|
||||
x.SelectedSize.Width = 1;
|
||||
x.SelectedSize.Height = 1;
|
||||
x.SelectedSize.Unit = ResizeUnit.Inch;
|
||||
}));
|
||||
|
||||
operation.Execute();
|
||||
|
||||
AssertEx.Image(_directory.File(), image => Assert.Equal(image.Frames[0].DpiX, image.Frames[0].PixelWidth, 0));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Transform_honors_fit_when_Fit()
|
||||
{
|
||||
var operation = new ResizeOperation(
|
||||
"Test.png",
|
||||
_directory,
|
||||
Settings(x => x.SelectedSize.Fit = ResizeFit.Fit));
|
||||
|
||||
operation.Execute();
|
||||
|
||||
AssertEx.Image(
|
||||
_directory.File(),
|
||||
image =>
|
||||
{
|
||||
Assert.Equal(96, image.Frames[0].PixelWidth);
|
||||
Assert.Equal(48, image.Frames[0].PixelHeight);
|
||||
});
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Transform_honors_fit_when_Fill()
|
||||
{
|
||||
var operation = new ResizeOperation(
|
||||
"Test.png",
|
||||
_directory,
|
||||
Settings(x => x.SelectedSize.Fit = ResizeFit.Fill));
|
||||
|
||||
operation.Execute();
|
||||
|
||||
AssertEx.Image(
|
||||
_directory.File(),
|
||||
image =>
|
||||
{
|
||||
Assert.Equal(Colors.White, image.Frames[0].GetFirstPixel());
|
||||
Assert.Equal(96, image.Frames[0].PixelWidth);
|
||||
Assert.Equal(96, image.Frames[0].PixelHeight);
|
||||
});
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Transform_honors_fit_when_Stretch()
|
||||
{
|
||||
var operation = new ResizeOperation(
|
||||
"Test.png",
|
||||
_directory,
|
||||
Settings(x => x.SelectedSize.Fit = ResizeFit.Stretch));
|
||||
|
||||
operation.Execute();
|
||||
|
||||
AssertEx.Image(
|
||||
_directory.File(),
|
||||
image =>
|
||||
{
|
||||
Assert.Equal(Colors.Black, image.Frames[0].GetFirstPixel());
|
||||
Assert.Equal(96, image.Frames[0].PixelWidth);
|
||||
Assert.Equal(96, image.Frames[0].PixelHeight);
|
||||
});
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetDestinationPath_uniquifies_output_filename()
|
||||
{
|
||||
File.WriteAllBytes(Path.Combine(_directory, "Test (Test).png"), new byte[0]);
|
||||
|
||||
var operation = new ResizeOperation("Test.png", _directory, Settings());
|
||||
|
||||
operation.Execute();
|
||||
|
||||
Assert.Contains("Test (Test) (1).png", _directory.FileNames);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetDestinationPath_uniquifies_output_filename_again()
|
||||
{
|
||||
File.WriteAllBytes(Path.Combine(_directory, "Test (Test).png"), new byte[0]);
|
||||
File.WriteAllBytes(Path.Combine(_directory, "Test (Test) (1).png"), new byte[0]);
|
||||
|
||||
var operation = new ResizeOperation("Test.png", _directory, Settings());
|
||||
|
||||
operation.Execute();
|
||||
|
||||
Assert.Contains("Test (Test) (2).png", _directory.FileNames);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetDestinationPath_uses_fileName_format()
|
||||
{
|
||||
var operation = new ResizeOperation(
|
||||
"Test.png",
|
||||
_directory,
|
||||
Settings(s => s.FileName = "%1_%2_%3_%4_%5_%6"));
|
||||
|
||||
operation.Execute();
|
||||
|
||||
Assert.Contains("Test_Test_96_96_96_48.png", _directory.FileNames);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Execute_handles_directories_in_fileName_format()
|
||||
{
|
||||
var operation = new ResizeOperation(
|
||||
"Test.png",
|
||||
_directory,
|
||||
Settings(s => s.FileName = @"Directory\%1 (%2)"));
|
||||
|
||||
operation.Execute();
|
||||
|
||||
Assert.True(File.Exists(_directory + @"\Directory\Test (Test).png"));
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
=> _directory.Dispose();
|
||||
|
||||
private Settings Settings(Action<Settings> action = null)
|
||||
{
|
||||
var settings = new Settings
|
||||
{
|
||||
Sizes = new ObservableCollection<ResizeSize>
|
||||
{
|
||||
new ResizeSize
|
||||
{
|
||||
Name = "Test",
|
||||
Width = 96,
|
||||
Height = 96,
|
||||
},
|
||||
},
|
||||
SelectedSizeIndex = 0,
|
||||
};
|
||||
action?.Invoke(settings);
|
||||
|
||||
return settings;
|
||||
}
|
||||
}
|
||||
}
|
||||
272
src/modules/imageresizer/tests/Models/ResizeSizeTests.cs
Normal file
272
src/modules/imageresizer/tests/Models/ResizeSizeTests.cs
Normal file
@@ -0,0 +1,272 @@
|
||||
// Copyright (c) Brice Lambson
|
||||
// The Brice Lambson licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information. Code forked from Brice Lambson's https://github.com/bricelam/ImageResizer/
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using ImageResizer.Properties;
|
||||
using ImageResizer.Test;
|
||||
using Xunit;
|
||||
using Xunit.Extensions;
|
||||
|
||||
namespace ImageResizer.Models
|
||||
{
|
||||
public class ResizeSizeTests
|
||||
{
|
||||
[Fact]
|
||||
public void Name_works()
|
||||
{
|
||||
var size = new ResizeSize();
|
||||
|
||||
var e = AssertEx.Raises<PropertyChangedEventArgs>(
|
||||
h => size.PropertyChanged += h,
|
||||
h => size.PropertyChanged -= h,
|
||||
() => size.Name = "Test");
|
||||
|
||||
Assert.Equal("Test", size.Name);
|
||||
Assert.Equal(nameof(ResizeSize.Name), e.Arguments.PropertyName);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Name_replaces_tokens()
|
||||
{
|
||||
var args = new List<(string, string)>
|
||||
{
|
||||
("$small$", Resources.Small),
|
||||
("$medium$", Resources.Medium),
|
||||
("$large$", Resources.Large),
|
||||
("$phone$", Resources.Phone),
|
||||
};
|
||||
foreach (var (name, expected) in args)
|
||||
{
|
||||
var size = new ResizeSize();
|
||||
|
||||
size.Name = name;
|
||||
|
||||
Assert.Equal(expected, size.Name);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Fit_works()
|
||||
{
|
||||
var size = new ResizeSize();
|
||||
|
||||
var e = AssertEx.Raises<PropertyChangedEventArgs>(
|
||||
h => size.PropertyChanged += h,
|
||||
h => size.PropertyChanged -= h,
|
||||
() => size.Fit = ResizeFit.Stretch);
|
||||
|
||||
Assert.Equal(ResizeFit.Stretch, size.Fit);
|
||||
Assert.Equal(nameof(ResizeSize.Fit), e.Arguments.PropertyName);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Width_works()
|
||||
{
|
||||
var size = new ResizeSize();
|
||||
|
||||
var e = AssertEx.Raises<PropertyChangedEventArgs>(
|
||||
h => size.PropertyChanged += h,
|
||||
h => size.PropertyChanged -= h,
|
||||
() => size.Width = 42);
|
||||
|
||||
Assert.Equal(42, size.Width);
|
||||
Assert.Equal(nameof(ResizeSize.Width), e.Arguments.PropertyName);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Height_works()
|
||||
{
|
||||
var size = new ResizeSize();
|
||||
|
||||
var e = AssertEx.Raises<PropertyChangedEventArgs>(
|
||||
h => size.PropertyChanged += h,
|
||||
h => size.PropertyChanged -= h,
|
||||
() => size.Height = 42);
|
||||
|
||||
Assert.Equal(42, size.Height);
|
||||
Assert.Equal(nameof(ResizeSize.Height), e.Arguments.PropertyName);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void HasAuto_returns_true_when_Width_unset()
|
||||
{
|
||||
var size = new ResizeSize
|
||||
{
|
||||
Width = 0,
|
||||
Height = 42,
|
||||
};
|
||||
|
||||
Assert.True(size.HasAuto);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void HasAuto_returns_true_when_Height_unset()
|
||||
{
|
||||
var size = new ResizeSize
|
||||
{
|
||||
Width = 42,
|
||||
Height = 0,
|
||||
};
|
||||
|
||||
Assert.True(size.HasAuto);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void HasAuto_returns_false_when_Width_and_Height_set()
|
||||
{
|
||||
var size = new ResizeSize
|
||||
{
|
||||
Width = 42,
|
||||
Height = 42,
|
||||
};
|
||||
|
||||
Assert.False(size.HasAuto);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Unit_works()
|
||||
{
|
||||
var size = new ResizeSize();
|
||||
|
||||
var e = AssertEx.Raises<PropertyChangedEventArgs>(
|
||||
h => size.PropertyChanged += h,
|
||||
h => size.PropertyChanged -= h,
|
||||
() => size.Unit = ResizeUnit.Inch);
|
||||
|
||||
Assert.Equal(ResizeUnit.Inch, size.Unit);
|
||||
Assert.Equal(nameof(ResizeSize.Unit), e.Arguments.PropertyName);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetPixelWidth_works()
|
||||
{
|
||||
var size = new ResizeSize
|
||||
{
|
||||
Width = 1,
|
||||
Unit = ResizeUnit.Inch,
|
||||
};
|
||||
|
||||
var result = size.GetPixelWidth(100, 96);
|
||||
|
||||
Assert.Equal(96, result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetPixelHeight_works()
|
||||
{
|
||||
var size = new ResizeSize
|
||||
{
|
||||
Height = 1,
|
||||
Unit = ResizeUnit.Inch,
|
||||
};
|
||||
|
||||
var result = size.GetPixelHeight(100, 96);
|
||||
|
||||
Assert.Equal(96, result);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(ResizeFit.Fit)]
|
||||
[InlineData(ResizeFit.Fill)]
|
||||
public void GetPixelHeight_uses_Width_when_scale_by_percent(ResizeFit fit)
|
||||
{
|
||||
var size = new ResizeSize
|
||||
{
|
||||
Fit = fit,
|
||||
Width = 100,
|
||||
Height = 50,
|
||||
Unit = ResizeUnit.Percent,
|
||||
};
|
||||
|
||||
var result = size.GetPixelHeight(100, 96);
|
||||
|
||||
Assert.Equal(100, result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ConvertToPixels_works_when_auto_and_fit()
|
||||
{
|
||||
var size = new ResizeSize
|
||||
{
|
||||
Width = 0,
|
||||
Fit = ResizeFit.Fit,
|
||||
};
|
||||
|
||||
var result = size.GetPixelWidth(100, 96);
|
||||
|
||||
Assert.Equal(double.PositiveInfinity, result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ConvertToPixels_works_when_auto_and_not_fit()
|
||||
{
|
||||
var size = new ResizeSize
|
||||
{
|
||||
Width = 0,
|
||||
Fit = ResizeFit.Fill,
|
||||
};
|
||||
|
||||
var result = size.GetPixelWidth(100, 96);
|
||||
|
||||
Assert.Equal(100, result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ConvertToPixels_works_when_inches()
|
||||
{
|
||||
var size = new ResizeSize
|
||||
{
|
||||
Width = 0.5,
|
||||
Unit = ResizeUnit.Inch,
|
||||
};
|
||||
|
||||
var result = size.GetPixelWidth(100, 96);
|
||||
|
||||
Assert.Equal(48, result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ConvertToPixels_works_when_centimeters()
|
||||
{
|
||||
var size = new ResizeSize
|
||||
{
|
||||
Width = 1,
|
||||
Unit = ResizeUnit.Centimeter,
|
||||
};
|
||||
|
||||
var result = size.GetPixelWidth(100, 96);
|
||||
|
||||
Assert.Equal(38, result, 0);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ConvertToPixels_works_when_percent()
|
||||
{
|
||||
var size = new ResizeSize
|
||||
{
|
||||
Width = 50,
|
||||
Unit = ResizeUnit.Percent,
|
||||
};
|
||||
|
||||
var result = size.GetPixelWidth(200, 96);
|
||||
|
||||
Assert.Equal(100, result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ConvertToPixels_works_when_pixels()
|
||||
{
|
||||
var size = new ResizeSize
|
||||
{
|
||||
Width = 50,
|
||||
Unit = ResizeUnit.Pixel,
|
||||
};
|
||||
|
||||
var result = size.GetPixelWidth(100, 96);
|
||||
|
||||
Assert.Equal(50, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
26
src/modules/imageresizer/tests/Properties/AppFixture.cs
Normal file
26
src/modules/imageresizer/tests/Properties/AppFixture.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
|
||||
[module: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1636:FileHeaderCopyrightTextMustMatch", Justification = "File created under PowerToys.")]
|
||||
|
||||
namespace ImageResizer.Properties
|
||||
{
|
||||
public class AppFixture : IDisposable
|
||||
{
|
||||
public AppFixture()
|
||||
{
|
||||
// new App() needs to be created since Settings.Reload() uses App.Current to update properties on the UI thread. App() can be created only once otherwise it results in System.InvalidOperationException : Cannot create more than one System.Windows.Application instance in the same AppDomain.
|
||||
imageResizerApp = new App();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
imageResizerApp = null;
|
||||
}
|
||||
|
||||
private App imageResizerApp;
|
||||
}
|
||||
}
|
||||
280
src/modules/imageresizer/tests/Properties/SettingsTests.cs
Normal file
280
src/modules/imageresizer/tests/Properties/SettingsTests.cs
Normal file
@@ -0,0 +1,280 @@
|
||||
// Copyright (c) Brice Lambson
|
||||
// The Brice Lambson licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information. Code forked from Brice Lambson's https://github.com/bricelam/ImageResizer/
|
||||
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Collections.Specialized;
|
||||
using System.ComponentModel;
|
||||
using ImageResizer.Models;
|
||||
using ImageResizer.Test;
|
||||
using Xunit;
|
||||
using Xunit.Abstractions;
|
||||
using Xunit.Extensions;
|
||||
|
||||
namespace ImageResizer.Properties
|
||||
{
|
||||
public class SettingsTests : IClassFixture<AppFixture>, IDisposable
|
||||
{
|
||||
public SettingsTests()
|
||||
{
|
||||
// Change settings.json path to a temp file
|
||||
Settings.SettingsPath = ".\\test_settings.json";
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (System.IO.File.Exists(Settings.SettingsPath))
|
||||
{
|
||||
System.IO.File.Delete(Settings.SettingsPath);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AllSizes_propagates_Sizes_collection_events()
|
||||
{
|
||||
var settings = new Settings
|
||||
{
|
||||
Sizes = new ObservableCollection<ResizeSize>(),
|
||||
CustomSize = new CustomSize(),
|
||||
};
|
||||
var ncc = (INotifyCollectionChanged)settings.AllSizes;
|
||||
|
||||
var result = AssertEx.Raises<NotifyCollectionChangedEventArgs>(
|
||||
h => ncc.CollectionChanged += h,
|
||||
h => ncc.CollectionChanged -= h,
|
||||
() => settings.Sizes.Add(new ResizeSize()));
|
||||
|
||||
Assert.Equal(NotifyCollectionChangedAction.Add, result.Arguments.Action);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AllSizes_propagates_Sizes_property_events()
|
||||
{
|
||||
var settings = new Settings
|
||||
{
|
||||
Sizes = new ObservableCollection<ResizeSize>(),
|
||||
CustomSize = new CustomSize(),
|
||||
};
|
||||
|
||||
Assert.PropertyChanged(
|
||||
(INotifyPropertyChanged)settings.AllSizes,
|
||||
"Item[]",
|
||||
() => settings.Sizes.Add(new ResizeSize()));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AllSizes_contains_Sizes()
|
||||
{
|
||||
var settings = new Settings
|
||||
{
|
||||
Sizes = new ObservableCollection<ResizeSize> { new ResizeSize() },
|
||||
CustomSize = new CustomSize(),
|
||||
};
|
||||
|
||||
Assert.Contains(settings.Sizes[0], settings.AllSizes);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AllSizes_contains_CustomSize()
|
||||
{
|
||||
var settings = new Settings
|
||||
{
|
||||
Sizes = new ObservableCollection<ResizeSize>(),
|
||||
CustomSize = new CustomSize(),
|
||||
};
|
||||
|
||||
Assert.Contains(settings.CustomSize, settings.AllSizes);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AllSizes_handles_property_events_for_CustomSize()
|
||||
{
|
||||
var originalCustomSize = new CustomSize();
|
||||
var settings = new Settings
|
||||
{
|
||||
Sizes = new ObservableCollection<ResizeSize>(),
|
||||
CustomSize = originalCustomSize,
|
||||
};
|
||||
var ncc = (INotifyCollectionChanged)settings.AllSizes;
|
||||
|
||||
var result = AssertEx.Raises<NotifyCollectionChangedEventArgs>(
|
||||
h => ncc.CollectionChanged += h,
|
||||
h => ncc.CollectionChanged -= h,
|
||||
() => settings.CustomSize = new CustomSize());
|
||||
|
||||
Assert.Equal(NotifyCollectionChangedAction.Replace, result.Arguments.Action);
|
||||
Assert.Equal(1, result.Arguments.NewItems.Count);
|
||||
Assert.Equal(settings.CustomSize, result.Arguments.NewItems[0]);
|
||||
Assert.Equal(0, result.Arguments.NewStartingIndex);
|
||||
Assert.Equal(1, result.Arguments.OldItems.Count);
|
||||
Assert.Equal(originalCustomSize, result.Arguments.OldItems[0]);
|
||||
Assert.Equal(0, result.Arguments.OldStartingIndex);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void FileNameFormat_works()
|
||||
{
|
||||
var settings = new Settings { FileName = "{T}%1e%2s%3t%4%5%6%7" };
|
||||
|
||||
var result = settings.FileNameFormat;
|
||||
|
||||
Assert.Equal("{{T}}{0}e{1}s{2}t{3}{4}{5}%7", result);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(0)]
|
||||
[InlineData(1)]
|
||||
[InlineData(2)]
|
||||
public void SelectedSize_returns_CustomSize_when_out_of_range(int index)
|
||||
{
|
||||
var settings = new Settings
|
||||
{
|
||||
SelectedSizeIndex = index,
|
||||
Sizes = new ObservableCollection<ResizeSize>(),
|
||||
CustomSize = new CustomSize(),
|
||||
};
|
||||
|
||||
var result = settings.SelectedSize;
|
||||
|
||||
Assert.Same(settings.CustomSize, result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SelectedSize_returns_Size_when_in_range()
|
||||
{
|
||||
var settings = new Settings
|
||||
{
|
||||
SelectedSizeIndex = 0,
|
||||
Sizes = new ObservableCollection<ResizeSize>
|
||||
{
|
||||
new ResizeSize(),
|
||||
},
|
||||
};
|
||||
|
||||
var result = settings.SelectedSize;
|
||||
|
||||
Assert.Same(settings.Sizes[0], result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void IDataErrorInfo_Error_returns_empty()
|
||||
{
|
||||
var settings = new Settings();
|
||||
|
||||
var result = ((IDataErrorInfo)settings).Error;
|
||||
|
||||
Assert.Empty(result);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(0)]
|
||||
[InlineData(101)]
|
||||
public void IDataErrorInfo_Item_JpegQualityLevel_returns_error_when_out_of_range(int value)
|
||||
{
|
||||
var settings = new Settings { JpegQualityLevel = value };
|
||||
|
||||
var result = ((IDataErrorInfo)settings)["JpegQualityLevel"];
|
||||
|
||||
Assert.Equal(
|
||||
string.Format(Resources.ValueMustBeBetween, 1, 100),
|
||||
result);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(1)]
|
||||
[InlineData(100)]
|
||||
public void IDataErrorInfo_Item_JpegQualityLevel_returns_empty_when_in_range(int value)
|
||||
{
|
||||
var settings = new Settings { JpegQualityLevel = value };
|
||||
|
||||
var result = ((IDataErrorInfo)settings)["JpegQualityLevel"];
|
||||
|
||||
Assert.Empty(result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void IDataErrorInfo_Item_returns_empty_when_not_JpegQualityLevel()
|
||||
{
|
||||
var settings = new Settings();
|
||||
|
||||
var result = ((IDataErrorInfo)settings)["Unknown"];
|
||||
|
||||
Assert.Empty(result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Reload_createsFile_when_FileNotFound()
|
||||
{
|
||||
// Arrange
|
||||
var settings = new Settings();
|
||||
|
||||
// Assert
|
||||
Assert.False(System.IO.File.Exists(Settings.SettingsPath));
|
||||
|
||||
// Act
|
||||
settings.Reload();
|
||||
|
||||
// Assert
|
||||
Assert.True(System.IO.File.Exists(Settings.SettingsPath));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Save_creates_file()
|
||||
{
|
||||
// Arrange
|
||||
var settings = new Settings();
|
||||
|
||||
// Assert
|
||||
Assert.False(System.IO.File.Exists(Settings.SettingsPath));
|
||||
|
||||
// Act
|
||||
settings.Save();
|
||||
|
||||
// Assert
|
||||
Assert.True(System.IO.File.Exists(Settings.SettingsPath));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Save_json_is_readable_by_Reload()
|
||||
{
|
||||
// Arrange
|
||||
var settings = new Settings();
|
||||
|
||||
// Assert
|
||||
Assert.False(System.IO.File.Exists(Settings.SettingsPath));
|
||||
|
||||
// Act
|
||||
settings.Save();
|
||||
settings.Reload(); // If the JSON file created by Save() is not readable this function will throw an error
|
||||
|
||||
// Assert
|
||||
Assert.True(System.IO.File.Exists(Settings.SettingsPath));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Reload_raises_PropertyChanged_()
|
||||
{
|
||||
// Arrange
|
||||
var settings = new Settings();
|
||||
settings.Save(); // To create the settings file
|
||||
|
||||
// Act
|
||||
var action = new System.Action(settings.Reload);
|
||||
|
||||
// Assert
|
||||
Assert.PropertyChanged(settings, "ShrinkOnly", action);
|
||||
Assert.PropertyChanged(settings, "Replace", action);
|
||||
Assert.PropertyChanged(settings, "IgnoreOrientation", action);
|
||||
Assert.PropertyChanged(settings, "JpegQualityLevel", action);
|
||||
Assert.PropertyChanged(settings, "PngInterlaceOption", action);
|
||||
Assert.PropertyChanged(settings, "TiffCompressOption", action);
|
||||
Assert.PropertyChanged(settings, "FileName", action);
|
||||
Assert.PropertyChanged(settings, "Sizes", action);
|
||||
Assert.PropertyChanged(settings, "KeepDateModified", action);
|
||||
Assert.PropertyChanged(settings, "FallbackEncoder", action);
|
||||
Assert.PropertyChanged(settings, "CustomSize", action);
|
||||
Assert.PropertyChanged(settings, "SelectedSizeIndex", action);
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
src/modules/imageresizer/tests/Test.gif
Normal file
BIN
src/modules/imageresizer/tests/Test.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.7 KiB |
BIN
src/modules/imageresizer/tests/Test.ico
Normal file
BIN
src/modules/imageresizer/tests/Test.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.3 KiB |
BIN
src/modules/imageresizer/tests/Test.jpg
Normal file
BIN
src/modules/imageresizer/tests/Test.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 7.6 KiB |
BIN
src/modules/imageresizer/tests/Test.png
Normal file
BIN
src/modules/imageresizer/tests/Test.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 781 B |
87
src/modules/imageresizer/tests/Test/AssertEx.cs
Normal file
87
src/modules/imageresizer/tests/Test/AssertEx.cs
Normal file
@@ -0,0 +1,87 @@
|
||||
// Copyright (c) Brice Lambson
|
||||
// The Brice Lambson licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information. Code forked from Brice Lambson's https://github.com/bricelam/ImageResizer/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
using System.Windows.Media.Imaging;
|
||||
using Xunit;
|
||||
|
||||
namespace ImageResizer.Test
|
||||
{
|
||||
internal static class AssertEx
|
||||
{
|
||||
public static void All<T>(IEnumerable<T> collection, Action<T> action)
|
||||
{
|
||||
foreach (var item in collection)
|
||||
{
|
||||
action(item);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Image(string path, Action<BitmapDecoder> action)
|
||||
{
|
||||
using (var stream = File.OpenRead(path))
|
||||
{
|
||||
var image = BitmapDecoder.Create(
|
||||
stream,
|
||||
BitmapCreateOptions.PreservePixelFormat,
|
||||
BitmapCacheOption.None);
|
||||
|
||||
action(image);
|
||||
}
|
||||
}
|
||||
|
||||
public static RaisedEvent<NotifyCollectionChangedEventArgs> Raises<T>(
|
||||
Action<NotifyCollectionChangedEventHandler> attach,
|
||||
Action<NotifyCollectionChangedEventHandler> detach,
|
||||
Action testCode)
|
||||
where T : NotifyCollectionChangedEventArgs
|
||||
{
|
||||
RaisedEvent<NotifyCollectionChangedEventArgs> raisedEvent = null;
|
||||
NotifyCollectionChangedEventHandler handler = (sender, e)
|
||||
=> raisedEvent = new RaisedEvent<NotifyCollectionChangedEventArgs>(sender, e);
|
||||
attach(handler);
|
||||
testCode();
|
||||
detach(handler);
|
||||
|
||||
Assert.NotNull(raisedEvent);
|
||||
|
||||
return raisedEvent;
|
||||
}
|
||||
|
||||
public static RaisedEvent<PropertyChangedEventArgs> Raises<T>(
|
||||
Action<PropertyChangedEventHandler> attach,
|
||||
Action<PropertyChangedEventHandler> detach,
|
||||
Action testCode)
|
||||
where T : PropertyChangedEventArgs
|
||||
{
|
||||
RaisedEvent<PropertyChangedEventArgs> raisedEvent = null;
|
||||
PropertyChangedEventHandler handler = (sender, e)
|
||||
=> raisedEvent = new RaisedEvent<PropertyChangedEventArgs>(sender, e);
|
||||
attach(handler);
|
||||
testCode();
|
||||
detach(handler);
|
||||
|
||||
Assert.NotNull(raisedEvent);
|
||||
|
||||
return raisedEvent;
|
||||
}
|
||||
|
||||
public class RaisedEvent<TArgs>
|
||||
{
|
||||
public RaisedEvent(object sender, TArgs args)
|
||||
{
|
||||
Sender = sender;
|
||||
Arguments = args;
|
||||
}
|
||||
|
||||
public object Sender { get; }
|
||||
|
||||
public TArgs Arguments { get; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
// Copyright (c) Brice Lambson
|
||||
// The Brice Lambson licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information. Code forked from Brice Lambson's https://github.com/bricelam/ImageResizer/
|
||||
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
|
||||
namespace ImageResizer.Test
|
||||
{
|
||||
internal static class BitmapSourceExtensions
|
||||
{
|
||||
public static Color GetFirstPixel(this BitmapSource source)
|
||||
{
|
||||
var pixel = new byte[4];
|
||||
new FormatConvertedBitmap(
|
||||
new CroppedBitmap(source, new Int32Rect(0, 0, 1, 1)),
|
||||
PixelFormats.Bgra32,
|
||||
destinationPalette: null,
|
||||
alphaThreshold: 0)
|
||||
.CopyPixels(pixel, 4, 0);
|
||||
|
||||
return Color.FromArgb(pixel[3], pixel[2], pixel[1], pixel[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
57
src/modules/imageresizer/tests/Test/TestDirectory.cs
Normal file
57
src/modules/imageresizer/tests/Test/TestDirectory.cs
Normal file
@@ -0,0 +1,57 @@
|
||||
// Copyright (c) Brice Lambson
|
||||
// The Brice Lambson licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information. Code forked from Brice Lambson's https://github.com/bricelam/ImageResizer/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using Xunit;
|
||||
using IOPath = System.IO.Path;
|
||||
|
||||
namespace ImageResizer
|
||||
{
|
||||
public class TestDirectory : IDisposable
|
||||
{
|
||||
private readonly string _path;
|
||||
|
||||
public TestDirectory()
|
||||
{
|
||||
_path = IOPath.Combine(
|
||||
AppDomain.CurrentDomain.BaseDirectory,
|
||||
IOPath.GetRandomFileName());
|
||||
Directory.CreateDirectory(_path);
|
||||
}
|
||||
|
||||
private IEnumerable<string> Files
|
||||
=> Directory.EnumerateFiles(_path);
|
||||
|
||||
public IEnumerable<string> FileNames
|
||||
=> Files.Select(IOPath.GetFileName);
|
||||
|
||||
public string File()
|
||||
=> Assert.Single(Files);
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
var stopwatch = Stopwatch.StartNew();
|
||||
while (stopwatch.ElapsedMilliseconds < 30000)
|
||||
{
|
||||
try
|
||||
{
|
||||
Directory.Delete(_path, recursive: true);
|
||||
break;
|
||||
}
|
||||
catch
|
||||
{
|
||||
Thread.Sleep(150);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static implicit operator string(TestDirectory directory)
|
||||
=> directory._path;
|
||||
}
|
||||
}
|
||||
BIN
src/modules/imageresizer/tests/TestPortrait.png
Normal file
BIN
src/modules/imageresizer/tests/TestPortrait.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 656 B |
@@ -0,0 +1,46 @@
|
||||
// Copyright (c) Brice Lambson
|
||||
// The Brice Lambson licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information. Code forked from Brice Lambson's https://github.com/bricelam/ImageResizer/
|
||||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using ImageResizer.Properties;
|
||||
using Xunit;
|
||||
using Xunit.Extensions;
|
||||
|
||||
namespace ImageResizer.Views
|
||||
{
|
||||
public class TimeRemainingConverterTests
|
||||
{
|
||||
[Theory]
|
||||
[InlineData("HourMinute", 1, 1, 0)]
|
||||
[InlineData("HourMinutes", 1, 2, 0)]
|
||||
[InlineData("HoursMinute", 2, 1, 0)]
|
||||
[InlineData("HoursMinutes", 2, 2, 0)]
|
||||
[InlineData("MinuteSecond", 0, 1, 1)]
|
||||
[InlineData("MinuteSeconds", 0, 1, 2)]
|
||||
[InlineData("MinutesSecond", 0, 2, 1)]
|
||||
[InlineData("MinutesSeconds", 0, 2, 2)]
|
||||
[InlineData("Second", 0, 0, 1)]
|
||||
[InlineData("Seconds", 0, 0, 2)]
|
||||
public void Convert_works(string resource, int hours, int minutes, int seconds)
|
||||
{
|
||||
var timeRemaining = new TimeSpan(hours, minutes, seconds);
|
||||
var converter = new TimeRemainingConverter();
|
||||
|
||||
var result = converter.Convert(
|
||||
timeRemaining,
|
||||
targetType: null,
|
||||
parameter: null,
|
||||
CultureInfo.InvariantCulture);
|
||||
|
||||
Assert.Equal(
|
||||
string.Format(
|
||||
Resources.ResourceManager.GetString("Progress_TimeRemaining_" + resource),
|
||||
hours,
|
||||
minutes,
|
||||
seconds),
|
||||
result);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user