From c84f4ba28253170d67c54cb98cbfc18c2d5c163b Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Fri, 21 Jan 2022 14:45:17 +1100 Subject: [PATCH] Replace generic dictionary with specialized collection type. --- .../Commands/CommandCollection.cs | 89 +++++++++++++++++++ .../Commands/CommandCollectionExtensions.cs | 25 ++++++ src/ImageSharp.Web/Commands/IRequestParser.cs | 2 +- .../PresetOnlyQueryCollectionRequestParser.cs | 26 +++--- .../Commands/QueryCollectionRequestParser.cs | 11 +-- .../Middleware/ImageCommandContext.cs | 7 +- .../Middleware/ImageProcessingContext.cs | 7 +- .../Middleware/ImageSharpMiddleware.cs | 11 +-- .../Processors/BackgroundColorWebProcessor.cs | 2 +- .../Processors/FormatWebProcessor.cs | 5 +- .../Processors/IImageWebProcessor.cs | 8 +- .../Processors/QualityWebProcessor.cs | 4 +- .../Processors/ResizeWebProcessor.cs | 51 ++++++----- .../Processors/WebProcessingExtensions.cs | 2 +- ...etOnlyQueryCollectionRequestParserTests.cs | 8 +- .../Commands/QueryCollectionUriParserTests.cs | 10 +-- .../DependencyInjection/MockWebProcessor.cs | 2 +- .../BackgroundColorWebProcessorTests.cs | 7 +- .../Processors/FormatWebProcessorTests.cs | 7 +- .../Processors/QualityWebProcessorTests.cs | 14 +-- .../Processors/ResizeWebProcessorTests.cs | 20 ++--- .../TestUtilities/CacheBusterWebProcessor.cs | 2 +- 22 files changed, 221 insertions(+), 99 deletions(-) create mode 100644 src/ImageSharp.Web/Commands/CommandCollection.cs create mode 100644 src/ImageSharp.Web/Commands/CommandCollectionExtensions.cs diff --git a/src/ImageSharp.Web/Commands/CommandCollection.cs b/src/ImageSharp.Web/Commands/CommandCollection.cs new file mode 100644 index 00000000..3909c49a --- /dev/null +++ b/src/ImageSharp.Web/Commands/CommandCollection.cs @@ -0,0 +1,89 @@ +// Copyright (c) Six Labors. +// Licensed under the Apache License, Version 2.0. + +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; + +namespace SixLabors.ImageSharp.Web.Commands +{ + /// + /// Represents an ordered collection of processing commands. + /// + public sealed class CommandCollection : KeyedCollection> + { + private readonly List keys = new(); + + /// + /// Initializes a new instance of the class. + /// + public CommandCollection() + : this(StringComparer.OrdinalIgnoreCase) + { + } + + private CommandCollection(IEqualityComparer comparer) + : base(comparer) + { + } + + /// + /// Gets an representing the keys of the collection. + /// + public ICollection Keys => this.keys; + + /// + /// Gets the command value with the specified key. + /// + /// The key of the element to get. + /// + /// The command value with the specified key. If a value with the specified key is not + /// found, an exception is thrown. + /// + /// is null. + /// An element with the specified key does not exist in the collection. + public new string this[string key] + { + get + { + if (this.TryGetValue(key, out KeyValuePair item)) + { + return item.Key; + } + + throw new KeyNotFoundException(); + } + } + + /// + protected override void InsertItem(int index, KeyValuePair item) + { + base.InsertItem(index, item); + this.keys.Insert(index, item.Key); + } + + /// + protected override void RemoveItem(int index) + { + base.RemoveItem(index); + this.keys.RemoveAt(index); + } + + /// + protected override void SetItem(int index, KeyValuePair item) + { + base.SetItem(index, item); + this.keys[index] = item.Key; + } + + /// + protected override void ClearItems() + { + base.ClearItems(); + this.keys.Clear(); + } + + /// + protected override string GetKeyForItem(KeyValuePair item) => item.Key; + } +} diff --git a/src/ImageSharp.Web/Commands/CommandCollectionExtensions.cs b/src/ImageSharp.Web/Commands/CommandCollectionExtensions.cs new file mode 100644 index 00000000..c438e5eb --- /dev/null +++ b/src/ImageSharp.Web/Commands/CommandCollectionExtensions.cs @@ -0,0 +1,25 @@ +// Copyright (c) Six Labors. +// Licensed under the Apache License, Version 2.0. + +using System.Collections.Generic; + +namespace SixLabors.ImageSharp.Web.Commands +{ + /// + /// Extension methods for . + /// + public static class CommandCollectionExtensions + { + /// + /// Gets the value associated with the specified key or the default value. + /// + /// The collection instance. + /// The key of the value to get. + /// The value associated with the specified key or the default value. + public static string GetValueOrDefault(this CommandCollection collection, string key) + { + collection.TryGetValue(key, out KeyValuePair result); + return result.Value; + } + } +} diff --git a/src/ImageSharp.Web/Commands/IRequestParser.cs b/src/ImageSharp.Web/Commands/IRequestParser.cs index 0e44c33c..e725cf05 100644 --- a/src/ImageSharp.Web/Commands/IRequestParser.cs +++ b/src/ImageSharp.Web/Commands/IRequestParser.cs @@ -16,6 +16,6 @@ public interface IRequestParser /// /// Encapsulates all HTTP-specific information about an individual HTTP request. /// The . - IDictionary ParseRequestCommands(HttpContext context); + CommandCollection ParseRequestCommands(HttpContext context); } } diff --git a/src/ImageSharp.Web/Commands/PresetOnlyQueryCollectionRequestParser.cs b/src/ImageSharp.Web/Commands/PresetOnlyQueryCollectionRequestParser.cs index 67fc51ca..2ee5a975 100644 --- a/src/ImageSharp.Web/Commands/PresetOnlyQueryCollectionRequestParser.cs +++ b/src/ImageSharp.Web/Commands/PresetOnlyQueryCollectionRequestParser.cs @@ -1,4 +1,4 @@ -// Copyright (c) Six Labors. +// Copyright (c) Six Labors. // Licensed under the Apache License, Version 2.0. using System; @@ -16,7 +16,7 @@ namespace SixLabors.ImageSharp.Web.Commands /// public class PresetOnlyQueryCollectionRequestParser : IRequestParser { - private readonly IDictionary> presets; + private readonly IDictionary presets; /// /// The command constant for the preset query parameter. @@ -31,31 +31,33 @@ public PresetOnlyQueryCollectionRequestParser(IOptions - public IDictionary ParseRequestCommands(HttpContext context) + public CommandCollection ParseRequestCommands(HttpContext context) { if (context.Request.Query.Count == 0 || !context.Request.Query.ContainsKey(QueryKey)) { - return new Dictionary(StringComparer.OrdinalIgnoreCase); + return new(); } - var requestedPreset = context.Request.Query["preset"][0]; - return this.presets.GetValueOrDefault(requestedPreset) ?? new Dictionary(StringComparer.OrdinalIgnoreCase); + string requestedPreset = context.Request.Query["preset"][0]; + return this.presets.GetValueOrDefault(requestedPreset) ?? new(); } - private static IDictionary> ParsePresets( + private static IDictionary ParsePresets( IDictionary unparsedPresets) => unparsedPresets .Select(keyValue => - new KeyValuePair>(keyValue.Key, ParsePreset(keyValue.Value))) + new KeyValuePair(keyValue.Key, ParsePreset(keyValue.Value))) .ToDictionary(keyValue => keyValue.Key, keyValue => keyValue.Value, StringComparer.OrdinalIgnoreCase); - private static IDictionary ParsePreset(string unparsedPresetValue) + private static CommandCollection ParsePreset(string unparsedPresetValue) { + // TODO: Investigate skipping the double allocation here. + // In .NET 6 we can directly use the QueryStringEnumerable type and enumerate stright to our command collection Dictionary parsed = QueryHelpers.ParseQuery(unparsedPresetValue); - var transformed = new Dictionary(parsed.Count, StringComparer.OrdinalIgnoreCase); - foreach (KeyValuePair keyValue in parsed) + CommandCollection transformed = new(); + foreach (KeyValuePair pair in parsed) { - transformed[keyValue.Key] = keyValue.Value.ToString(); + transformed.Add(new(pair.Key, pair.Value.ToString())); } return transformed; diff --git a/src/ImageSharp.Web/Commands/QueryCollectionRequestParser.cs b/src/ImageSharp.Web/Commands/QueryCollectionRequestParser.cs index 698879b8..0bbed1cb 100644 --- a/src/ImageSharp.Web/Commands/QueryCollectionRequestParser.cs +++ b/src/ImageSharp.Web/Commands/QueryCollectionRequestParser.cs @@ -1,7 +1,6 @@ // Copyright (c) Six Labors. // Licensed under the Apache License, Version 2.0. -using System; using System.Collections.Generic; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.WebUtilities; @@ -15,18 +14,20 @@ namespace SixLabors.ImageSharp.Web.Commands public sealed class QueryCollectionRequestParser : IRequestParser { /// - public IDictionary ParseRequestCommands(HttpContext context) + public CommandCollection ParseRequestCommands(HttpContext context) { if (context.Request.Query.Count == 0) { - return new Dictionary(StringComparer.OrdinalIgnoreCase); + return new(); } + // TODO: Investigate skipping the double allocation here. + // In .NET 6 we can directly use the QueryStringEnumerable type and enumerate stright to our command collection Dictionary parsed = QueryHelpers.ParseQuery(context.Request.QueryString.ToUriComponent()); - var transformed = new Dictionary(parsed.Count, StringComparer.OrdinalIgnoreCase); + CommandCollection transformed = new(); foreach (KeyValuePair pair in parsed) { - transformed[pair.Key] = pair.Value.ToString(); + transformed.Add(new(pair.Key, pair.Value.ToString())); } return transformed; diff --git a/src/ImageSharp.Web/Middleware/ImageCommandContext.cs b/src/ImageSharp.Web/Middleware/ImageCommandContext.cs index 3cd9cb02..890f689d 100644 --- a/src/ImageSharp.Web/Middleware/ImageCommandContext.cs +++ b/src/ImageSharp.Web/Middleware/ImageCommandContext.cs @@ -1,7 +1,6 @@ // Copyright (c) Six Labors. // Licensed under the Apache License, Version 2.0. -using System.Collections.Generic; using System.Globalization; using Microsoft.AspNetCore.Http; using SixLabors.ImageSharp.Web.Commands; @@ -22,7 +21,7 @@ public class ImageCommandContext /// The culture used to parse commands. public ImageCommandContext( HttpContext context, - IDictionary commands, + CommandCollection commands, CommandParser parser, CultureInfo culture) { @@ -38,9 +37,9 @@ public ImageCommandContext( public HttpContext Context { get; } /// - /// Gets the dictionary containing the collection of URI derived processing commands. + /// Gets the collection of URI derived processing commands. /// - public IDictionary Commands { get; } + public CommandCollection Commands { get; } /// /// Gets the command parser for parsing URI derived processing commands. diff --git a/src/ImageSharp.Web/Middleware/ImageProcessingContext.cs b/src/ImageSharp.Web/Middleware/ImageProcessingContext.cs index f96ae9c6..3fb79105 100644 --- a/src/ImageSharp.Web/Middleware/ImageProcessingContext.cs +++ b/src/ImageSharp.Web/Middleware/ImageProcessingContext.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.IO; using Microsoft.AspNetCore.Http; +using SixLabors.ImageSharp.Web.Commands; namespace SixLabors.ImageSharp.Web.Middleware { @@ -23,7 +24,7 @@ public class ImageProcessingContext public ImageProcessingContext( HttpContext context, Stream stream, - IDictionary commands, + CommandCollection commands, string contentType, string extension) { @@ -47,10 +48,10 @@ public ImageProcessingContext( /// /// Gets the parsed collection of processing commands. /// - public IDictionary Commands { get; } + public CommandCollection Commands { get; } /// - /// Gets the content type for for the processed image. + /// Gets the content type for the processed image. /// public string ContentType { get; } diff --git a/src/ImageSharp.Web/Middleware/ImageSharpMiddleware.cs b/src/ImageSharp.Web/Middleware/ImageSharpMiddleware.cs index 71f2c8e1..c6c4f8aa 100644 --- a/src/ImageSharp.Web/Middleware/ImageSharpMiddleware.cs +++ b/src/ImageSharp.Web/Middleware/ImageSharpMiddleware.cs @@ -172,18 +172,15 @@ public ImageSharpMiddleware( this.asyncKeyLock = asyncKeyLock; } -#pragma warning disable IDE1006 // Naming Styles /// /// Performs operations upon the current request. /// /// The current HTTP request context. /// The . public async Task Invoke(HttpContext context) -#pragma warning restore IDE1006 // Naming Styles { // We expect to get concrete collection type which removes virtual dispatch concerns and enumerator allocations - IDictionary parsedCommands = this.requestParser.ParseRequestCommands(context); - Dictionary commands = parsedCommands as Dictionary ?? new Dictionary(parsedCommands, StringComparer.OrdinalIgnoreCase); + CommandCollection commands = this.requestParser.ParseRequestCommands(context); if (commands.Count > 0) { @@ -243,7 +240,7 @@ await this.ProcessRequestAsync( commands); } - private void StripUnknownCommands(Dictionary commands, int startAtIndex) + private void StripUnknownCommands(CommandCollection commands, int startAtIndex) { var keys = new List(commands.Keys); for (int index = startAtIndex; index < keys.Count; index++) @@ -260,7 +257,7 @@ private async Task ProcessRequestAsync( HttpContext context, IImageResolver sourceImageResolver, ImageContext imageContext, - IDictionary commands) + CommandCollection commands) { // Create a cache key based on all the components of the requested url string uri = GetUri(context, commands); @@ -511,7 +508,7 @@ private async Task SendResponseAsync( } } - private static string GetUri(HttpContext context, IDictionary commands) + private static string GetUri(HttpContext context, CommandCollection commands) { var sb = new StringBuilder(context.Request.Host.ToString()); diff --git a/src/ImageSharp.Web/Processors/BackgroundColorWebProcessor.cs b/src/ImageSharp.Web/Processors/BackgroundColorWebProcessor.cs index b324b659..bc596943 100644 --- a/src/ImageSharp.Web/Processors/BackgroundColorWebProcessor.cs +++ b/src/ImageSharp.Web/Processors/BackgroundColorWebProcessor.cs @@ -32,7 +32,7 @@ private static readonly IEnumerable ColorCommands public FormattedImage Process( FormattedImage image, ILogger logger, - IDictionary commands, + CommandCollection commands, CommandParser parser, CultureInfo culture) { diff --git a/src/ImageSharp.Web/Processors/FormatWebProcessor.cs b/src/ImageSharp.Web/Processors/FormatWebProcessor.cs index 6fbc7b68..a9036533 100644 --- a/src/ImageSharp.Web/Processors/FormatWebProcessor.cs +++ b/src/ImageSharp.Web/Processors/FormatWebProcessor.cs @@ -46,7 +46,7 @@ public FormatWebProcessor(IOptions options) public FormattedImage Process( FormattedImage image, ILogger logger, - IDictionary commands, + CommandCollection commands, CommandParser parser, CultureInfo culture) { @@ -54,8 +54,7 @@ public FormattedImage Process( if (!string.IsNullOrWhiteSpace(extension)) { - IImageFormat format = this.options.Configuration - .ImageFormatsManager.FindFormatByFileExtension(extension); + IImageFormat format = this.options.Configuration.ImageFormatsManager.FindFormatByFileExtension(extension); if (format != null) { diff --git a/src/ImageSharp.Web/Processors/IImageWebProcessor.cs b/src/ImageSharp.Web/Processors/IImageWebProcessor.cs index 93a12d49..2393de24 100644 --- a/src/ImageSharp.Web/Processors/IImageWebProcessor.cs +++ b/src/ImageSharp.Web/Processors/IImageWebProcessor.cs @@ -14,16 +14,16 @@ namespace SixLabors.ImageSharp.Web.Processors public interface IImageWebProcessor { /// - /// Gets the collection of recognized querystring commands. + /// Gets the collection of recognized command keys. /// IEnumerable Commands { get; } /// - /// Processes the image based on the querystring commands. + /// Processes the image based on the given commands. /// /// The image to process. /// The type used for performing logging. - /// The querystring collection containing the processing commands. + /// The ordered collection containing the processing commands. /// The command parser use for parting commands. /// /// The to use as the current parsing culture. @@ -32,7 +32,7 @@ public interface IImageWebProcessor FormattedImage Process( FormattedImage image, ILogger logger, - IDictionary commands, + CommandCollection commands, CommandParser parser, CultureInfo culture); } diff --git a/src/ImageSharp.Web/Processors/QualityWebProcessor.cs b/src/ImageSharp.Web/Processors/QualityWebProcessor.cs index 4c1353aa..7b91d97a 100644 --- a/src/ImageSharp.Web/Processors/QualityWebProcessor.cs +++ b/src/ImageSharp.Web/Processors/QualityWebProcessor.cs @@ -34,11 +34,11 @@ private static readonly IEnumerable QualityCommands public FormattedImage Process( FormattedImage image, ILogger logger, - IDictionary commands, + CommandCollection commands, CommandParser parser, CultureInfo culture) { - if (commands.ContainsKey(Quality)) + if (commands.Contains(Quality)) { // The encoders clamp any values so no validation is required. int quality = parser.ParseValue(commands.GetValueOrDefault(Quality), culture); diff --git a/src/ImageSharp.Web/Processors/ResizeWebProcessor.cs b/src/ImageSharp.Web/Processors/ResizeWebProcessor.cs index 459fa379..4b775f42 100644 --- a/src/ImageSharp.Web/Processors/ResizeWebProcessor.cs +++ b/src/ImageSharp.Web/Processors/ResizeWebProcessor.cs @@ -69,7 +69,7 @@ private static readonly IEnumerable ResizeCommands public FormattedImage Process( FormattedImage image, ILogger logger, - IDictionary commands, + CommandCollection commands, CommandParser parser, CultureInfo culture) { @@ -84,11 +84,11 @@ public FormattedImage Process( } private static ResizeOptions GetResizeOptions( - IDictionary commands, + CommandCollection commands, CommandParser parser, CultureInfo culture) { - if (!commands.ContainsKey(Width) && !commands.ContainsKey(Height)) + if (!commands.Contains(Width) && !commands.Contains(Height)) { return null; } @@ -116,7 +116,7 @@ private static ResizeOptions GetResizeOptions( } private static Size ParseSize( - IDictionary commands, + CommandCollection commands, CommandParser parser, CultureInfo culture) { @@ -128,7 +128,7 @@ private static Size ParseSize( } private static PointF? GetCenter( - IDictionary commands, + CommandCollection commands, CommandParser parser, CultureInfo culture) { @@ -143,24 +143,24 @@ private static Size ParseSize( } private static ResizeMode GetMode( - IDictionary commands, + CommandCollection commands, CommandParser parser, CultureInfo culture) => parser.ParseValue(commands.GetValueOrDefault(Mode), culture); private static AnchorPositionMode GetAnchor( - IDictionary commands, + CommandCollection commands, CommandParser parser, CultureInfo culture) => parser.ParseValue(commands.GetValueOrDefault(Anchor), culture); private static bool GetCompandMode( - IDictionary commands, + CommandCollection commands, CommandParser parser, CultureInfo culture) => parser.ParseValue(commands.GetValueOrDefault(Compand), culture); - private static IResampler GetSampler(IDictionary commands) + private static IResampler GetSampler(CommandCollection commands) { string sampler = commands.GetValueOrDefault(Sampler); @@ -171,23 +171,34 @@ private static IResampler GetSampler(IDictionary commands) case "nearest": case "nearestneighbor": return KnownResamplers.NearestNeighbor; - case "box": return KnownResamplers.Box; + case "box": + return KnownResamplers.Box; case "mitchell": case "mitchellnetravali": return KnownResamplers.MitchellNetravali; case "catmull": case "catmullrom": return KnownResamplers.CatmullRom; - case "lanczos2": return KnownResamplers.Lanczos2; - case "lanczos3": return KnownResamplers.Lanczos3; - case "lanczos5": return KnownResamplers.Lanczos5; - case "lanczos8": return KnownResamplers.Lanczos8; - case "welch": return KnownResamplers.Welch; - case "robidoux": return KnownResamplers.Robidoux; - case "robidouxsharp": return KnownResamplers.RobidouxSharp; - case "spline": return KnownResamplers.Spline; - case "triangle": return KnownResamplers.Triangle; - case "hermite": return KnownResamplers.Hermite; + case "lanczos2": + return KnownResamplers.Lanczos2; + case "lanczos3": + return KnownResamplers.Lanczos3; + case "lanczos5": + return KnownResamplers.Lanczos5; + case "lanczos8": + return KnownResamplers.Lanczos8; + case "welch": + return KnownResamplers.Welch; + case "robidoux": + return KnownResamplers.Robidoux; + case "robidouxsharp": + return KnownResamplers.RobidouxSharp; + case "spline": + return KnownResamplers.Spline; + case "triangle": + return KnownResamplers.Triangle; + case "hermite": + return KnownResamplers.Hermite; } } diff --git a/src/ImageSharp.Web/Processors/WebProcessingExtensions.cs b/src/ImageSharp.Web/Processors/WebProcessingExtensions.cs index 12afce58..68f589a7 100644 --- a/src/ImageSharp.Web/Processors/WebProcessingExtensions.cs +++ b/src/ImageSharp.Web/Processors/WebProcessingExtensions.cs @@ -30,7 +30,7 @@ public static FormattedImage Process( this FormattedImage source, ILogger logger, IEnumerable processors, - IDictionary commands, + CommandCollection commands, CommandParser commandParser, CultureInfo culture) { diff --git a/tests/ImageSharp.Web.Tests/Commands/PresetOnlyQueryCollectionRequestParserTests.cs b/tests/ImageSharp.Web.Tests/Commands/PresetOnlyQueryCollectionRequestParserTests.cs index e96d08f0..8b669c19 100644 --- a/tests/ImageSharp.Web.Tests/Commands/PresetOnlyQueryCollectionRequestParserTests.cs +++ b/tests/ImageSharp.Web.Tests/Commands/PresetOnlyQueryCollectionRequestParserTests.cs @@ -22,7 +22,7 @@ public void PresetOnlyQueryCollectionRequestParserExtractsCommands() }; HttpContext context = CreateHttpContext("?preset=Preset1"); - IDictionary actual = new PresetOnlyQueryCollectionRequestParser(Options.Create(new PresetOnlyQueryCollectionRequestParserOptions + CommandCollection actual = new PresetOnlyQueryCollectionRequestParser(Options.Create(new PresetOnlyQueryCollectionRequestParserOptions { Presets = new Dictionary(StringComparer.OrdinalIgnoreCase) { @@ -43,7 +43,7 @@ public void PresetOnlyQueryCollectionRequestParserExtractsCommandsWithOtherCasin }; HttpContext context = CreateHttpContext("?PRESET=PRESET1"); - IDictionary actual = new PresetOnlyQueryCollectionRequestParser(Options.Create(new PresetOnlyQueryCollectionRequestParserOptions + CommandCollection actual = new PresetOnlyQueryCollectionRequestParser(Options.Create(new PresetOnlyQueryCollectionRequestParserOptions { Presets = new Dictionary(StringComparer.OrdinalIgnoreCase) { @@ -60,7 +60,7 @@ public void PresetOnlyQueryCollectionRequestParserCommandsWithoutPresetParam() IDictionary expected = new Dictionary(); HttpContext context = CreateHttpContext("?test=test"); - IDictionary actual = new PresetOnlyQueryCollectionRequestParser(Options.Create(new PresetOnlyQueryCollectionRequestParserOptions + CommandCollection actual = new PresetOnlyQueryCollectionRequestParser(Options.Create(new PresetOnlyQueryCollectionRequestParserOptions { Presets = new Dictionary(StringComparer.OrdinalIgnoreCase) { @@ -77,7 +77,7 @@ public void PresetOnlyQueryCollectionRequestParserCommandsWithoutMatchingPreset( IDictionary expected = new Dictionary(); HttpContext context = CreateHttpContext("?preset=Preset2"); - IDictionary actual = new PresetOnlyQueryCollectionRequestParser(Options.Create(new PresetOnlyQueryCollectionRequestParserOptions + CommandCollection actual = new PresetOnlyQueryCollectionRequestParser(Options.Create(new PresetOnlyQueryCollectionRequestParserOptions { Presets = new Dictionary(StringComparer.OrdinalIgnoreCase) { diff --git a/tests/ImageSharp.Web.Tests/Commands/QueryCollectionUriParserTests.cs b/tests/ImageSharp.Web.Tests/Commands/QueryCollectionUriParserTests.cs index 8e67f9ce..e083473a 100644 --- a/tests/ImageSharp.Web.Tests/Commands/QueryCollectionUriParserTests.cs +++ b/tests/ImageSharp.Web.Tests/Commands/QueryCollectionUriParserTests.cs @@ -1,8 +1,6 @@ // Copyright (c) Six Labors. // Licensed under the Apache License, Version 2.0. -using System; -using System.Collections.Generic; using Microsoft.AspNetCore.Http; using SixLabors.ImageSharp.Web.Commands; using Xunit; @@ -14,14 +12,14 @@ public class QueryCollectionUriParserTests [Fact] public void QueryCollectionParserExtractsCommands() { - IDictionary expected = new Dictionary(StringComparer.OrdinalIgnoreCase) + CommandCollection expected = new() { - { "width", "400" }, - { "height", "200" } + { new("width", "400") }, + { new("height", "200") } }; HttpContext context = CreateHttpContext(); - IDictionary actual = new QueryCollectionRequestParser().ParseRequestCommands(context); + CommandCollection actual = new QueryCollectionRequestParser().ParseRequestCommands(context); Assert.Equal(expected, actual); } diff --git a/tests/ImageSharp.Web.Tests/DependencyInjection/MockWebProcessor.cs b/tests/ImageSharp.Web.Tests/DependencyInjection/MockWebProcessor.cs index 2eb1d5dd..b047e178 100644 --- a/tests/ImageSharp.Web.Tests/DependencyInjection/MockWebProcessor.cs +++ b/tests/ImageSharp.Web.Tests/DependencyInjection/MockWebProcessor.cs @@ -17,7 +17,7 @@ public class MockWebProcessor : IImageWebProcessor public FormattedImage Process( FormattedImage image, ILogger logger, - IDictionary commands, + CommandCollection commands, CommandParser parser, CultureInfo culture) => image; diff --git a/tests/ImageSharp.Web.Tests/Processors/BackgroundColorWebProcessorTests.cs b/tests/ImageSharp.Web.Tests/Processors/BackgroundColorWebProcessorTests.cs index 2f934a62..5dfee886 100644 --- a/tests/ImageSharp.Web.Tests/Processors/BackgroundColorWebProcessorTests.cs +++ b/tests/ImageSharp.Web.Tests/Processors/BackgroundColorWebProcessorTests.cs @@ -1,7 +1,6 @@ // Copyright (c) Six Labors. // Licensed under the Apache License, Version 2.0. -using System.Collections.Generic; using System.Globalization; using SixLabors.ImageSharp.Formats.Png; using SixLabors.ImageSharp.PixelFormats; @@ -17,12 +16,12 @@ public class BackgroundColorWebProcessorTests [Fact] public void BackgroundColorWebProcessor_UpdatesColor() { - var parser = new CommandParser(new[] { new ColorConverter() }); + CommandParser parser = new(new[] { new ColorConverter() }); CultureInfo culture = CultureInfo.InvariantCulture; - var commands = new Dictionary + CommandCollection commands = new() { - { BackgroundColorWebProcessor.Color, nameof(Color.Orange) } + { new(BackgroundColorWebProcessor.Color, nameof(Color.Orange)) } }; using var image = new Image(1, 1); diff --git a/tests/ImageSharp.Web.Tests/Processors/FormatWebProcessorTests.cs b/tests/ImageSharp.Web.Tests/Processors/FormatWebProcessorTests.cs index 19cc7538..1baaa626 100644 --- a/tests/ImageSharp.Web.Tests/Processors/FormatWebProcessorTests.cs +++ b/tests/ImageSharp.Web.Tests/Processors/FormatWebProcessorTests.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. using System; -using System.Collections.Generic; using System.Globalization; using Microsoft.Extensions.Options; using SixLabors.ImageSharp.Formats.Gif; @@ -21,12 +20,12 @@ public class FormatWebProcessorTests [Fact] public void FormatWebProcessor_UpdatesFormat() { - var parser = new CommandParser(Array.Empty()); + CommandParser parser = new(Array.Empty()); CultureInfo culture = CultureInfo.InvariantCulture; - var commands = new Dictionary + CommandCollection commands = new() { - { FormatWebProcessor.Format, GifFormat.Instance.Name }, + { new(FormatWebProcessor.Format, GifFormat.Instance.Name) }, }; using var image = new Image(1, 1); diff --git a/tests/ImageSharp.Web.Tests/Processors/QualityWebProcessorTests.cs b/tests/ImageSharp.Web.Tests/Processors/QualityWebProcessorTests.cs index 885f3ddf..8df3c827 100644 --- a/tests/ImageSharp.Web.Tests/Processors/QualityWebProcessorTests.cs +++ b/tests/ImageSharp.Web.Tests/Processors/QualityWebProcessorTests.cs @@ -18,12 +18,12 @@ public class QualityWebProcessorTests [Fact] public void QualityWebProcessor_UpdatesJpegQuality() { - var parser = new CommandParser(new[] { new IntegralNumberConverter() }); + CommandParser parser = new(new[] { new IntegralNumberConverter() }); CultureInfo culture = CultureInfo.InvariantCulture; - var commands = new Dictionary + CommandCollection commands = new() { - { QualityWebProcessor.Quality, "42" }, + { new(QualityWebProcessor.Quality, "42") }, }; using var image = new Image(1, 1); @@ -41,12 +41,14 @@ public void QualityWebProcessor_UpdatesJpegQuality() [Fact] public void QualityWebProcessor_UpdatesWebpQuality() { - var parser = new CommandParser(new[] { new IntegralNumberConverter() }); + CommandParser parser = new(new[] { new IntegralNumberConverter() }); CultureInfo culture = CultureInfo.InvariantCulture; - var commands = new Dictionary + CommandCollection commands = new() { - { QualityWebProcessor.Quality, "42" }, + { + new(QualityWebProcessor.Quality, "42") + }, }; using var image = new Image(1, 1); diff --git a/tests/ImageSharp.Web.Tests/Processors/ResizeWebProcessorTests.cs b/tests/ImageSharp.Web.Tests/Processors/ResizeWebProcessorTests.cs index af0b5626..2408e67f 100644 --- a/tests/ImageSharp.Web.Tests/Processors/ResizeWebProcessorTests.cs +++ b/tests/ImageSharp.Web.Tests/Processors/ResizeWebProcessorTests.cs @@ -33,8 +33,8 @@ public class ResizeWebProcessorTests [InlineData(nameof(KnownResamplers.Welch))] public void ResizeWebProcessor_UpdatesSize(string resampler) { - const int Width = 4; - const int Height = 6; + const int width = 4; + const int height = 6; var converters = new List { @@ -48,21 +48,21 @@ public void ResizeWebProcessor_UpdatesSize(string resampler) var parser = new CommandParser(converters); CultureInfo culture = CultureInfo.InvariantCulture; - var commands = new Dictionary + CommandCollection commands = new() { - { ResizeWebProcessor.Sampler, resampler }, - { ResizeWebProcessor.Width, Width.ToString() }, - { ResizeWebProcessor.Height, Height.ToString() }, - { ResizeWebProcessor.Xy, "0,0" }, - { ResizeWebProcessor.Mode, nameof(ResizeMode.Stretch) } + { new(ResizeWebProcessor.Sampler, resampler) }, + { new(ResizeWebProcessor.Width, width.ToString()) }, + { new(ResizeWebProcessor.Height, height.ToString()) }, + { new(ResizeWebProcessor.Xy, "0,0") }, + { new(ResizeWebProcessor.Mode, nameof(ResizeMode.Stretch)) } }; using var image = new Image(1, 1); using var formatted = new FormattedImage(image, PngFormat.Instance); new ResizeWebProcessor().Process(formatted, null, commands, parser, culture); - Assert.Equal(Width, image.Width); - Assert.Equal(Height, image.Height); + Assert.Equal(width, image.Width); + Assert.Equal(height, image.Height); } } } diff --git a/tests/ImageSharp.Web.Tests/TestUtilities/CacheBusterWebProcessor.cs b/tests/ImageSharp.Web.Tests/TestUtilities/CacheBusterWebProcessor.cs index 21084aac..ac263fde 100644 --- a/tests/ImageSharp.Web.Tests/TestUtilities/CacheBusterWebProcessor.cs +++ b/tests/ImageSharp.Web.Tests/TestUtilities/CacheBusterWebProcessor.cs @@ -18,7 +18,7 @@ public class CacheBusterWebProcessor : IImageWebProcessor public FormattedImage Process( FormattedImage image, ILogger logger, - IDictionary commands, + CommandCollection commands, CommandParser parser, CultureInfo culture) => image;