From a5ef9520a210c87bf2a00af0e5ae0bce823f1bc1 Mon Sep 17 00:00:00 2001 From: Scott Williams Date: Wed, 15 Mar 2017 07:46:02 +0000 Subject: [PATCH] ensure all save operations pass along IEncoderOptions --- src/ImageSharp/Configuration.cs | 2 +- src/ImageSharp/IO/IFileSystem.cs | 10 +- src/ImageSharp/IO/LocalFileSystem.cs | 19 +- src/ImageSharp/Image/Image{TColor}.cs | 14 +- tests/ImageSharp.Tests/ConfigurationTests.cs | 2 +- tests/ImageSharp.Tests/IO/LocalFileSystem.cs | 6 +- .../ImageSharp.Tests/Image/ImageSaveTests.cs | 163 +++++++++++++++++- .../Image/SaveWatchingImage.cs | 9 +- 8 files changed, 195 insertions(+), 30 deletions(-) diff --git a/src/ImageSharp/Configuration.cs b/src/ImageSharp/Configuration.cs index 053ec0202..e0eb21865 100644 --- a/src/ImageSharp/Configuration.cs +++ b/src/ImageSharp/Configuration.cs @@ -56,7 +56,7 @@ namespace ImageSharp #if !NETSTANDARD1_1 /// - /// Helper for accessing the local file system. + /// Gets or sets the fielsystem helper for accessing the local file system. /// internal IFileSystem FileSystem { get; set; } = new LocalFileSystem(); #endif diff --git a/src/ImageSharp/IO/IFileSystem.cs b/src/ImageSharp/IO/IFileSystem.cs index 1ce4f25f4..ee1ef84d7 100644 --- a/src/ImageSharp/IO/IFileSystem.cs +++ b/src/ImageSharp/IO/IFileSystem.cs @@ -1,13 +1,13 @@ -// +// // Copyright (c) James Jackson-South and contributors. // Licensed under the Apache License, Version 2.0. // -using System.IO; - namespace ImageSharp.IO { -#if !NETSTANDARD1_1 + using System.IO; + + #if !NETSTANDARD1_1 /// /// A simple interface representing the filesystem. /// @@ -25,7 +25,7 @@ namespace ImageSharp.IO /// /// Path to the file to open. /// A stream representing the file to open. - Stream OpenWrite(string path); + Stream Create(string path); } #endif } diff --git a/src/ImageSharp/IO/LocalFileSystem.cs b/src/ImageSharp/IO/LocalFileSystem.cs index e32fc6733..02a9914ea 100644 --- a/src/ImageSharp/IO/LocalFileSystem.cs +++ b/src/ImageSharp/IO/LocalFileSystem.cs @@ -1,11 +1,16 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Text; +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// namespace ImageSharp.IO { -#if !NETSTANDARD1_1 + using System; + using System.Collections.Generic; + using System.IO; + using System.Text; + + #if !NETSTANDARD1_1 /// /// A wrapper around the local File apis. /// @@ -18,9 +23,9 @@ namespace ImageSharp.IO } /// - public Stream OpenWrite(string path) + public Stream Create(string path) { - return File.OpenWrite(path); + return File.Create(path); } } #endif diff --git a/src/ImageSharp/Image/Image{TColor}.cs b/src/ImageSharp/Image/Image{TColor}.cs index 0c4aaa784..2c9f15393 100644 --- a/src/ImageSharp/Image/Image{TColor}.cs +++ b/src/ImageSharp/Image/Image{TColor}.cs @@ -168,7 +168,8 @@ namespace ImageSharp : base(configuration) { Guard.NotNull(filePath, nameof(filePath)); - using (Stream fs = File.OpenRead(filePath)) + configuration = configuration ?? Configuration.Default; + using (Stream fs = configuration.FileSystem.OpenRead(filePath)) { this.Load(fs, options); } @@ -439,7 +440,7 @@ namespace ImageSharp throw new InvalidOperationException($"No image formats have been registered for the file extension '{ext}'."); } - return this.Save(filePath, format); + return this.Save(filePath, format, options); } /// @@ -465,10 +466,7 @@ namespace ImageSharp public Image Save(string filePath, IImageFormat format, IEncoderOptions options) { Guard.NotNull(format, nameof(format)); - using (FileStream fs = File.Create(filePath)) - { - return this.Save(fs, format); - } + return this.Save(filePath, format.Encoder, options); } /// @@ -494,9 +492,9 @@ namespace ImageSharp public Image Save(string filePath, IImageEncoder encoder, IEncoderOptions options) { Guard.NotNull(encoder, nameof(encoder)); - using (FileStream fs = File.Create(filePath)) + using (Stream fs = this.Configuration.FileSystem.Create(filePath)) { - return this.Save(fs, encoder); + return this.Save(fs, encoder, options); } } #endif diff --git a/tests/ImageSharp.Tests/ConfigurationTests.cs b/tests/ImageSharp.Tests/ConfigurationTests.cs index 043c3d3f1..c749239d7 100644 --- a/tests/ImageSharp.Tests/ConfigurationTests.cs +++ b/tests/ImageSharp.Tests/ConfigurationTests.cs @@ -21,7 +21,7 @@ namespace ImageSharp.Tests [Fact] public void DefaultsToLocalFileSystem() { - var configuration = Configuration.CreateDefaultInstance(); + Configuration configuration = Configuration.CreateDefaultInstance(); ImageSharp.IO.IFileSystem fs = configuration.FileSystem; diff --git a/tests/ImageSharp.Tests/IO/LocalFileSystem.cs b/tests/ImageSharp.Tests/IO/LocalFileSystem.cs index 71fbaa382..472d643cd 100644 --- a/tests/ImageSharp.Tests/IO/LocalFileSystem.cs +++ b/tests/ImageSharp.Tests/IO/LocalFileSystem.cs @@ -22,7 +22,7 @@ namespace ImageSharp.Tests.IO LocalFileSystem fs = new LocalFileSystem(); - using (var r = new StreamReader(fs.OpenRead(path))) + using (StreamReader r = new StreamReader(fs.OpenRead(path))) { string data = r.ReadToEnd(); @@ -33,13 +33,13 @@ namespace ImageSharp.Tests.IO } [Fact] - public void OpenWrite() + public void Create() { string path = Path.GetTempFileName(); string testData = Guid.NewGuid().ToString(); LocalFileSystem fs = new LocalFileSystem(); - using (var r = new StreamWriter(fs.OpenWrite(path))) + using (StreamWriter r = new StreamWriter(fs.Create(path))) { r.Write(testData); } diff --git a/tests/ImageSharp.Tests/Image/ImageSaveTests.cs b/tests/ImageSharp.Tests/Image/ImageSaveTests.cs index b6339ce8a..172a14dc2 100644 --- a/tests/ImageSharp.Tests/Image/ImageSaveTests.cs +++ b/tests/ImageSharp.Tests/Image/ImageSaveTests.cs @@ -20,10 +20,12 @@ namespace ImageSharp.Tests { private readonly SaveWatchingImage Image; private readonly Mock fileSystem; + private readonly IEncoderOptions encoderOptions; public ImageSaveTests() { this.fileSystem = new Mock(); + this.encoderOptions = new Mock().Object; this.Image = new SaveWatchingImage(1, 1, this.fileSystem.Object); } @@ -31,15 +33,170 @@ namespace ImageSharp.Tests public void SavePath() { Stream stream = new MemoryStream(); - this.fileSystem.Setup(x => x.OpenWrite("path")).Returns(stream); - this.Image.Save("path"); + this.fileSystem.Setup(x => x.Create("path.png")).Returns(stream); + this.Image.Save("path.png"); SaveWatchingImage.OperationDetails operation = this.Image.Saves.Single(); Assert.Equal(stream, operation.stream); - Assert.Equal(this.Image.CurrentImageFormat.Encoder, operation.encoder); + Assert.IsType(operation.encoder); Assert.Null(operation.options); } + [Fact] + public void SavePathWithOptions() + { + Stream stream = new MemoryStream(); + this.fileSystem.Setup(x => x.Create("path.jpg")).Returns(stream); + + this.Image.Save("path.jpg", this.encoderOptions); + + SaveWatchingImage.OperationDetails operation = this.Image.Saves.Single(); + Assert.Equal(stream, operation.stream); + Assert.IsType(operation.encoder); + Assert.Equal(this.encoderOptions, operation.options); + } + + [Fact] + public void SavePathWithEncoder() + { + Stream stream = new MemoryStream(); + this.fileSystem.Setup(x => x.Create("path.jpg")).Returns(stream); + + this.Image.Save("path.jpg", new BmpEncoder()); + + SaveWatchingImage.OperationDetails operation = this.Image.Saves.Single(); + Assert.Equal(stream, operation.stream); + Assert.IsType(operation.encoder); + Assert.Null(operation.options); + } + + [Fact] + public void SavePathWithEncoderAndOptions() + { + Stream stream = new MemoryStream(); + this.fileSystem.Setup(x => x.Create("path.jpg")).Returns(stream); + + this.Image.Save("path.jpg", new BmpEncoder(), this.encoderOptions); + + SaveWatchingImage.OperationDetails operation = this.Image.Saves.Single(); + Assert.Equal(stream, operation.stream); + Assert.IsType(operation.encoder); + Assert.Equal(this.encoderOptions, operation.options); + } + + + + [Fact] + public void SavePathWithFormat() + { + Stream stream = new MemoryStream(); + this.fileSystem.Setup(x => x.Create("path.jpg")).Returns(stream); + + this.Image.Save("path.jpg", new GifFormat()); + + SaveWatchingImage.OperationDetails operation = this.Image.Saves.Single(); + Assert.Equal(stream, operation.stream); + Assert.IsType(operation.encoder); + Assert.Null(operation.options); + } + + [Fact] + public void SavePathWithFormatAndOptions() + { + Stream stream = new MemoryStream(); + this.fileSystem.Setup(x => x.Create("path.jpg")).Returns(stream); + + this.Image.Save("path.jpg", new BmpFormat(), this.encoderOptions); + + SaveWatchingImage.OperationDetails operation = this.Image.Saves.Single(); + Assert.Equal(stream, operation.stream); + Assert.IsType(operation.encoder); + Assert.Equal(this.encoderOptions, operation.options); + } + + /// + /// ///////////////////////////////////////////////////////////// + /// + /// + + [Fact] + public void SaveStream() + { + Stream stream = new MemoryStream(); + this.Image.Save(stream); + + SaveWatchingImage.OperationDetails operation = this.Image.Saves.Single(); + Assert.Equal(stream, operation.stream); + Assert.IsType(this.Image.CurrentImageFormat.Encoder.GetType(), operation.encoder); + Assert.Null(operation.options); + } + + [Fact] + public void SaveStreamWithOptions() + { + Stream stream = new MemoryStream(); + + this.Image.Save(stream, this.encoderOptions); + + SaveWatchingImage.OperationDetails operation = this.Image.Saves.Single(); + Assert.Equal(stream, operation.stream); + Assert.IsType(this.Image.CurrentImageFormat.Encoder.GetType(), operation.encoder); + + Assert.Equal(this.encoderOptions, operation.options); + } + + [Fact] + public void SaveStreamWithEncoder() + { + Stream stream = new MemoryStream(); + + this.Image.Save(stream, new BmpEncoder()); + + SaveWatchingImage.OperationDetails operation = this.Image.Saves.Single(); + Assert.Equal(stream, operation.stream); + Assert.IsType(operation.encoder); + Assert.Null(operation.options); + } + + [Fact] + public void SaveStreamWithEncoderAndOptions() + { + Stream stream = new MemoryStream(); + + this.Image.Save(stream, new BmpEncoder(), this.encoderOptions); + + SaveWatchingImage.OperationDetails operation = this.Image.Saves.Single(); + Assert.Equal(stream, operation.stream); + Assert.IsType(operation.encoder); + Assert.Equal(this.encoderOptions, operation.options); + } + + [Fact] + public void SaveStreamWithFormat() + { + Stream stream = new MemoryStream(); + + this.Image.Save(stream, new GifFormat()); + + SaveWatchingImage.OperationDetails operation = this.Image.Saves.Single(); + Assert.Equal(stream, operation.stream); + Assert.IsType(operation.encoder); + Assert.Null(operation.options); + } + + [Fact] + public void SaveStreamWithFormatAndOptions() + { + Stream stream = new MemoryStream(); + + this.Image.Save(stream, new BmpFormat(), this.encoderOptions); + + SaveWatchingImage.OperationDetails operation = this.Image.Saves.Single(); + Assert.Equal(stream, operation.stream); + Assert.IsType(operation.encoder); + Assert.Equal(this.encoderOptions, operation.options); + } + public void Dispose() { this.Image.Dispose(); diff --git a/tests/ImageSharp.Tests/Image/SaveWatchingImage.cs b/tests/ImageSharp.Tests/Image/SaveWatchingImage.cs index 010ad6829..e9b45da69 100644 --- a/tests/ImageSharp.Tests/Image/SaveWatchingImage.cs +++ b/tests/ImageSharp.Tests/Image/SaveWatchingImage.cs @@ -16,7 +16,7 @@ namespace ImageSharp.Tests public class SaveWatchingImage : Image { public List Saves { get; } = new List(); - + public SaveWatchingImage(int width, int height, IFileSystem fs = null) : base(width, height, Configuration.CreateDefaultInstance()) { @@ -26,7 +26,12 @@ namespace ImageSharp.Tests internal override void SaveInternal(Stream stream, IImageEncoder encoder, IEncoderOptions options) { - + this.Saves.Add(new OperationDetails + { + encoder = encoder, + options = options, + stream = stream + }); } public struct OperationDetails