Skip to content

Commit

Permalink
Save ImageResizer settings in JSON format (#1258)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
arjunbalgovind authored Feb 13, 2020
1 parent 80c2356 commit cf0ed3d
Show file tree
Hide file tree
Showing 12 changed files with 433 additions and 351 deletions.
11 changes: 6 additions & 5 deletions installer/MSIX/PackagingLayout.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,13 @@
<File DestinationPath="modules\PowerRenameExt.dll" SourcePath="..\..\x64\Release\modules\PowerRenameExt.dll"/>
<File DestinationPath="modules\shortcut_guide.dll" SourcePath="..\..\x64\Release\modules\shortcut_guide.dll"/>
<File DestinationPath="modules\PowerRenameUWPUI.exe" SourcePath="..\..\x64\Release\PowerRenameUWPUI.exe"/>
<File DestinationPath="modules\ImageResizer.exe" SourcePath="..\..\x64\Release\ImageResizer.exe"/>
<File DestinationPath="modules\ImageResizer.exe" SourcePath="..\..\x64\Release\modules\ImageResizer.exe"/>
<File DestinationPath="modules\ImageResizerExt.dll" SourcePath="..\..\x64\Release\modules\ImageResizerExt.dll"/>
<File DestinationPath="modules\GalaSoft.MvvmLight.dll" SourcePath="..\..\x64\Release\GalaSoft.MvvmLight.dll"/>
<File DestinationPath="modules\GalaSoft.MvvmLight.Platform.dll" SourcePath="..\..\x64\Release\GalaSoft.MvvmLight.Platform.dll"/>
<File DestinationPath="modules\GalaSoft.MvvmLight.Extras.dll" SourcePath="..\..\x64\Release\GalaSoft.MvvmLight.Extras.dll"/>
<File DestinationPath="modules\System.Windows.Interactivity.dll" SourcePath="..\..\x64\Release\System.Windows.Interactivity.dll"/>
<File DestinationPath="modules\GalaSoft.MvvmLight.dll" SourcePath="..\..\x64\Release\modules\GalaSoft.MvvmLight.dll"/>
<File DestinationPath="modules\GalaSoft.MvvmLight.Platform.dll" SourcePath="..\..\x64\Release\modules\GalaSoft.MvvmLight.Platform.dll"/>
<File DestinationPath="modules\GalaSoft.MvvmLight.Extras.dll" SourcePath="..\..\x64\Release\modules\GalaSoft.MvvmLight.Extras.dll"/>
<File DestinationPath="modules\System.Windows.Interactivity.dll" SourcePath="..\..\x64\Release\modules\System.Windows.Interactivity.dll"/>
<File DestinationPath="modules\Newtonsoft.Json.dll" SourcePath="..\..\x64\Release\modules\Newtonsoft.Json.dll"/>

<File DestinationPath="svgs\*" SourcePath="..\..\x64\Release\svgs\*"/>
<File DestinationPath="settings-html\**" SourcePath="..\..\x64\Release\settings-html\**"/>
Expand Down
1 change: 1 addition & 0 deletions installer/PowerToysSetup/Product.wxs
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,7 @@
<!-- NB: Needed since it's only referenced in XAML. -->
<netfx:NativeImage Id="Interactivity" Platform="all" Priority="0"/>
</File>
<File Source="$(var.BinX64Dir)\modules\Newtonsoft.Json.dll" />
<File Source="$(var.BinX64Dir)\modules\ImageResizerExt.dll" KeyPath="yes" />
<RegistryKey Root="HKCR" Key="CLSID\{51B4D7E5-7568-4234-B4BB-47FB3C016A69}\InprocServer32">
<RegistryValue Value="[ModulesInstallFolder]ImageResizerExt.dll" Type="string" />
Expand Down
2 changes: 2 additions & 0 deletions src/modules/imageresizer/tests/ImageResizerUITest.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile>
</TargetFrameworkProfile>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
<DebugSymbols>true</DebugSymbols>
Expand Down Expand Up @@ -62,6 +63,7 @@
<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" />
Expand Down
26 changes: 26 additions & 0 deletions src/modules/imageresizer/tests/Properties/AppFixture.cs
Original file line number Diff line number Diff line change
@@ -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;
}
}
92 changes: 91 additions & 1 deletion src/modules/imageresizer/tests/Properties/SettingsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,34 @@
// 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
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()
{
Expand Down Expand Up @@ -186,5 +202,79 @@ public void IDataErrorInfo_Item_returns_empty_when_not_JpegQualityLevel()

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);
}
}
}
17 changes: 7 additions & 10 deletions src/modules/imageresizer/ui/ImageResizerUI.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
<WarningLevel>4</WarningLevel>
<TargetFrameworkProfile>
</TargetFrameworkProfile>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
<PlatformTarget>x64</PlatformTarget>
Expand Down Expand Up @@ -69,11 +70,6 @@
<Compile Include="Models\ResizeOperation.cs" />
<Compile Include="Models\ResizeSize.cs" />
<Compile Include="Models\ResizeUnit.cs" />
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
<DependentUpon>Settings.settings</DependentUpon>
</Compile>
<Compile Include="Utilities\MathHelpers.cs" />
<Compile Include="ViewModels\AdvancedViewModel.cs" />
<Compile Include="ViewModels\InputViewModel.cs" />
Expand Down Expand Up @@ -164,11 +160,6 @@
<EmbeddedResource Include="Properties\Resources.sk.resx" />
<EmbeddedResource Include="Properties\Resources.tr.resx" />
<EmbeddedResource Include="Properties\Resources.zh-Hans.resx" />
<None Include="Properties\Settings.settings">
<Generator>PublicSettingsSingleFileGenerator</Generator>
<SubType>Designer</SubType>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
</ItemGroup>
<ItemGroup>
<AdditionalFiles Include="..\codeAnalysis\StyleCop.json" />
Expand All @@ -186,11 +177,17 @@
<PackageReference Include="MvvmLightLibs">
<Version>5.4.1.1</Version>
</PackageReference>
<PackageReference Include="Newtonsoft.Json">
<Version>12.0.3</Version>
</PackageReference>
<PackageReference Include="StyleCop.Analyzers">
<Version>1.1.118</Version>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<TargetFrameworkSDKToolsDirectory Condition=" '$(Platform)' == 'x64'">$(TargetFrameworkSDKToolsDirectory)$(Platform)\</TargetFrameworkSDKToolsDirectory>
</PropertyGroup>
</Project>
16 changes: 15 additions & 1 deletion src/modules/imageresizer/ui/Models/CustomSize.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,29 @@
// 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 Newtonsoft.Json;

namespace ImageResizer.Models
{
public class CustomSize : ResizeSize
{
[JsonIgnore]
public override string Name
{
get => Resources.Input_Custom;
set { /* no-op */ }
}

public CustomSize(ResizeFit fit, double width, double height, ResizeUnit unit)
{
Fit = fit;
Width = width;
Height = height;
Unit = unit;
}

public CustomSize()
{
}
}
}
22 changes: 21 additions & 1 deletion src/modules/imageresizer/ui/Models/ResizeSize.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@
using System.Diagnostics;
using GalaSoft.MvvmLight;
using ImageResizer.Properties;

using Newtonsoft.Json;

namespace ImageResizer.Models
{
[JsonObject(MemberSerialization.OptIn)]
public class ResizeSize : ObservableObject
{
private static readonly IDictionary<string, string> _tokens;
Expand All @@ -29,12 +31,27 @@ static ResizeSize()
["$phone$"] = Resources.Phone,
};

public ResizeSize(string name, ResizeFit fit, double width, double height, ResizeUnit unit)
{
Name = name;
Fit = fit;
Width = width;
Height = height;
Unit = unit;
}

public ResizeSize()
{
}

[JsonProperty(PropertyName = "name")]
public virtual string Name
{
get => _name;
set => Set(nameof(Name), ref _name, ReplaceTokens(value));
}

[JsonProperty(PropertyName = "fit")]
public ResizeFit Fit
{
get => _fit;
Expand All @@ -47,12 +64,14 @@ public ResizeFit Fit
}
}

[JsonProperty(PropertyName = "width")]
public double Width
{
get => _width;
set => Set(nameof(Width), ref _width, value);
}

[JsonProperty(PropertyName = "height")]
public double Height
{
get => _height;
Expand All @@ -65,6 +84,7 @@ public bool ShowHeight
public bool HasAuto
=> Width == 0 || Height == 0;

[JsonProperty(PropertyName = "unit")]
public ResizeUnit Unit
{
get => _unit;
Expand Down
Loading

0 comments on commit cf0ed3d

Please sign in to comment.