Browse Source

1. 修正GetDaysOfMonth的bug
2. 新增高精度定时器HighAccurateTimer

懒得勤快 1 year ago
parent
commit
0b5e3a30f0

+ 2 - 2
Masuit.Tools.Abstractions/DateTimeExt/DateTimeHelper.cs

@@ -186,7 +186,7 @@ namespace Masuit.Tools.DateTimeExt
         /// <returns>天数</returns>
         public static int GetDaysOfMonth(this DateTime now)
         {
-            return now.Year switch
+            return now.Month switch
             {
                 1 => 31,
                 2 => DateTime.IsLeapYear(now.Year) ? 29 : 28,
@@ -429,4 +429,4 @@ namespace Masuit.Tools.DateTimeExt
         /// </summary>
         CloseOpen
     }
-}
+}

+ 1 - 1
Masuit.Tools.Abstractions/Masuit.Tools.Abstractions.csproj

@@ -3,7 +3,7 @@
         <TargetFrameworks>netstandard2.0;netstandard2.1;net461;net5;net6;net7;net8</TargetFrameworks>
         <LangVersion>latest</LangVersion>
         <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
-        <Version>2.6.9.1</Version>
+        <Version>2.6.9.2</Version>
         <Authors>懒得勤快</Authors>
         <Description>全龄段友好的C#万能工具库,码数吐司库,不管你是菜鸟新手还是骨灰级玩家都能轻松上手,Masuit.Tools基础公共库(适用于.NET4.6.1/.NET Standard2.0及以上项目),包含一些常用的操作类,大都是静态类,加密解密,反射操作,Excel简单导出,权重随机筛选算法,分布式短id,表达式树,linq扩展,文件压缩,多线程下载和FTP客户端,硬件信息,字符串扩展方法,日期时间扩展操作,中国农历,大文件拷贝,图像裁剪,验证码,断点续传,集合扩展等常用封装。
             官网教程:https://tools.masuit.org

+ 2 - 2
Masuit.Tools.Abstractions/Net/MultiThreadDownloader.cs

@@ -319,7 +319,7 @@ public class MultiThreadDownloader
         var start = division * order;
         var end = start + division - 1;
         end += order == parts - 1 ? remaining : 0;
-        return new PartialDownloader(_url, TempFileDirectory, SnowFlake.NewId, start, end, true);
+        return new PartialDownloader(_url, TempFileDirectory, Guid.NewGuid().ToString(), start, end, true);
     }
 
     /// <summary>
@@ -434,4 +434,4 @@ public class MultiThreadDownloader
     }
 
     #endregion 公共方法
-}
+}

+ 1 - 1
Masuit.Tools.Abstractions/Systems/HiPerfTimer.cs

@@ -116,4 +116,4 @@ public class HiPerfTimer
         timer.Stop();
         return timer.Duration;
     }
-}
+}

+ 102 - 0
Masuit.Tools.Abstractions/Systems/HighAccurateTimer.cs

@@ -0,0 +1,102 @@
+using System;
+using System.ComponentModel;
+using System.Runtime.InteropServices;
+using System.Threading;
+
+namespace Masuit.Tools.Systems;
+
+/// <summary>
+/// 高精度定时器,1ms精度
+/// </summary>
+public class HighAccurateTimer : Disposable
+{
+    private readonly long _clockFrequency; // result of QueryPerformanceFrequency()
+    private bool _running;
+    private Thread _timerThread;
+
+    private int _intervalMs; // interval in mimliseccond;
+
+    ///
+    /// Timer inteval in milisecond
+    ///
+    public int Interval
+    {
+        get => _intervalMs;
+        set
+        {
+            _intervalMs = value;
+            _intevalTicks = (long)(value * (double)_clockFrequency / 1000);
+        }
+    }
+
+    private long _intevalTicks;
+
+    [DllImport("Kernel32.dll")]
+    private static extern bool QueryPerformanceCounter(out long lpPerformanceCount);
+
+    [DllImport("Kernel32.dll")]
+    private static extern bool QueryPerformanceFrequency(out long lpFrequency);
+
+    public HighAccurateTimer(int interval = 1)
+    {
+        if (QueryPerformanceFrequency(out _clockFrequency) == false)
+        {
+            // Frequency not supported
+            throw new Win32Exception("QueryPerformanceFrequency() function is not supported");
+        }
+        Interval = interval;
+    }
+
+    public bool GetTick(out long currentTickCount)
+    {
+        if (QueryPerformanceCounter(out currentTickCount) == false)
+            throw new Win32Exception("QueryPerformanceCounter() failed!");
+        else
+            return true;
+    }
+
+    public void Start(Action func)
+    {
+        _running = true;
+        _timerThread = new Thread(() =>
+        {
+            GetTick(out var currTime);
+            var nextTriggerTime = currTime + _intevalTicks; // the time when next task will be executed
+            while (_running)
+            {
+                while (currTime < nextTriggerTime)
+                {
+                    GetTick(out currTime);
+                } // wailt an interval
+
+                nextTriggerTime = currTime + _intevalTicks;
+                func();
+            }
+        })
+        {
+            Name = "HighAccuracyTimer",
+            Priority = ThreadPriority.Highest
+        };
+
+        _timerThread.Start();
+    }
+
+    public void Stop()
+    {
+        _running = false;
+    }
+
+    ~HighAccurateTimer()
+    {
+        _running = false;
+    }
+
+    /// <summary>
+    /// 释放
+    /// </summary>
+    /// <param name="disposing"></param>
+    public override void Dispose(bool disposing)
+    {
+        Stop();
+    }
+}

+ 1 - 1
Masuit.Tools.AspNetCore/Masuit.Tools.AspNetCore.csproj

@@ -18,7 +18,7 @@
         <Product>Masuit.Tools.AspNetCore</Product>
         <PackageId>Masuit.Tools.AspNetCore</PackageId>
         <LangVersion>latest</LangVersion>
-        <Version>1.2.9.1</Version>
+        <Version>1.2.9.2</Version>
         <RepositoryType></RepositoryType>
         <GeneratePackageOnBuild>True</GeneratePackageOnBuild>
         <FileVersion>1.1.9</FileVersion>

+ 1 - 1
Masuit.Tools.Core/Masuit.Tools.Core.csproj

@@ -6,7 +6,7 @@
 官网教程:https://tools.masuit.org
 github:https://github.com/ldqk/Masuit.Tools
         </Description>
-        <Version>2.6.9.1</Version>
+        <Version>2.6.9.2</Version>
         <Copyright>Copyright © 懒得勤快</Copyright>
         <PackageProjectUrl>https://github.com/ldqk/Masuit.Tools</PackageProjectUrl>
         <PackageTags>Masuit.Tools,工具库,Utility,Crypt,Extensions</PackageTags>

+ 1 - 1
Masuit.Tools.Excel/Masuit.Tools.Excel.csproj

@@ -3,7 +3,7 @@
         <TargetFramework>netstandard2.0</TargetFramework>
         <LangVersion>latest</LangVersion>
         <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
-        <Version>1.2.9.1</Version>
+        <Version>1.2.9.2</Version>
         <Authors>懒得勤快</Authors>
         <Description>Masuit.Tools.Excel导出库,支持一些简单数据的导出,支持图片列</Description>
         <Copyright>懒得勤快</Copyright>

+ 3 - 0
Masuit.Tools.Net45/Masuit.Tools.Net45.csproj

@@ -228,6 +228,9 @@
     <Compile Include="..\Masuit.Tools.Abstractions\Systems\FallbackJsonPropertyResolver.cs">
       <Link>Systems\FallbackJsonPropertyResolver.cs</Link>
     </Compile>
+    <Compile Include="..\Masuit.Tools.Abstractions\Systems\HighAccurateTimer.cs">
+      <Link>Systems\HighAccurateTimer.cs</Link>
+    </Compile>
     <Compile Include="..\Masuit.Tools.Abstractions\Systems\HiPerfTimer.cs">
       <Link>Systems\HiPerfTimer.cs</Link>
     </Compile>

+ 1 - 1
Masuit.Tools.Net45/package.nuspec

@@ -2,7 +2,7 @@
 <package>
     <metadata>
         <id>Masuit.Tools.Net45</id>
-        <version>2.6.9.1</version>
+        <version>2.6.9.2</version>
         <title>Masuit.Tools</title>
         <authors>懒得勤快</authors>
         <owners>masuit.com</owners>

+ 2 - 2
Masuit.Tools.NoSQL.MongoDBClient/Masuit.Tools.NoSQL.MongoDBClient.csproj

@@ -2,7 +2,7 @@
 
   <PropertyGroup>
     <TargetFramework>netstandard2.1</TargetFramework>
-    <Version>1.8.7.2</Version>
+    <Version>1.8.7.3</Version>
     <Authors>懒得勤快</Authors>
     <Company>masuit.com</Company>
     <Description>包含MongoDB的所有的增删查改。
@@ -38,7 +38,7 @@
   </PropertyGroup>
 
   <ItemGroup>
-    <PackageReference Include="MongoDB.Driver" Version="2.23.1" />
+    <PackageReference Include="MongoDB.Driver" Version="2.24.0" />
   </ItemGroup>
 
 </Project>

+ 3 - 3
Masuit.Tools/Masuit.Tools.csproj

@@ -206,7 +206,7 @@
       <Version>1.7.0</Version>
     </PackageReference>
     <PackageReference Include="HtmlSanitizer">
-      <Version>8.0.811</Version>
+      <Version>8.0.843</Version>
     </PackageReference>
     <PackageReference Include="Microsoft.AspNet.Mvc">
       <Version>5.3.0</Version>
@@ -221,10 +221,10 @@
       <Version>1.0.0</Version>
     </PackageReference>
     <PackageReference Include="StackExchange.Redis">
-      <Version>2.7.17</Version>
+      <Version>2.7.20</Version>
     </PackageReference>
     <PackageReference Include="System.Text.Json">
-      <Version>8.0.1</Version>
+      <Version>8.0.2</Version>
     </PackageReference>
     <PackageReference Include="System.ValueTuple">
       <Version>4.5.0</Version>

+ 1 - 1
Masuit.Tools/package.nuspec

@@ -2,7 +2,7 @@
 <package>
     <metadata>
         <id>Masuit.Tools.Net</id>
-        <version>2.6.9.1</version>
+        <version>2.6.9.2</version>
         <title>Masuit.Tools</title>
         <authors>懒得勤快</authors>
         <owners>masuit.com</owners>

+ 4 - 4
Test/Masuit.Tools.Abstractions.Test/Masuit.Tools.Abstractions.Test.csproj

@@ -13,13 +13,13 @@
   </ItemGroup>
 
   <ItemGroup>
-    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
-    <PackageReference Include="xunit" Version="2.6.6" />
-    <PackageReference Include="xunit.runner.visualstudio" Version="2.5.6">
+    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
+    <PackageReference Include="xunit" Version="2.7.0" />
+    <PackageReference Include="xunit.runner.visualstudio" Version="2.5.7">
       <PrivateAssets>all</PrivateAssets>
       <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
     </PackageReference>
-    <PackageReference Include="coverlet.collector" Version="6.0.0">
+    <PackageReference Include="coverlet.collector" Version="6.0.1">
       <PrivateAssets>all</PrivateAssets>
       <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
     </PackageReference>

+ 4 - 4
Test/Masuit.Tools.Core.Test/Masuit.Tools.Core.Test.csproj

@@ -9,11 +9,11 @@
   </PropertyGroup>
 
   <ItemGroup>
-    <PackageReference Include="Microsoft.AspNetCore.TestHost" Version="8.0.1" />
+    <PackageReference Include="Microsoft.AspNetCore.TestHost" Version="8.0.2" />
     <PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
-    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
-    <PackageReference Include="xunit" Version="2.6.6" />
-    <PackageReference Include="xunit.runner.visualstudio" Version="2.5.6">
+    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
+    <PackageReference Include="xunit" Version="2.7.0" />
+    <PackageReference Include="xunit.runner.visualstudio" Version="2.5.7">
       <PrivateAssets>all</PrivateAssets>
       <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
     </PackageReference>

+ 8 - 11
Test/Masuit.Tools.Test/ExtensionMethodsTest.cs

@@ -1,31 +1,28 @@
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using Xunit;
-using Assert = Microsoft.VisualStudio.TestTools.UnitTesting.Assert;
+using Xunit;
 
 namespace Masuit.Tools.Test
 {
-    [TestClass]
     public class ExtensionMethodsTest
     {
-        [TestMethod]
+        [Fact]
         public void MatchUrl_True()
         {
             bool expect = "https://git.lug.us-tc.edu.cn/masuit/soft".MatchUrl();
-            Assert.AreEqual(true, expect);
+            Assert.Equal(true, expect);
         }
 
-        [TestMethod]
+        [Fact]
         public void MatchEmail()
         {
             var (expect, match) = "[email protected]".MatchEmail();
-            Assert.AreEqual(true, expect);
+            Assert.Equal(true, expect);
         }
 
-        [TestMethod]
+        [Fact]
         public void MatchIdentifyCard_False()
         {
             bool expect = "513901199509120610".MatchIdentifyCard();
-            Assert.AreEqual(false, expect);
+            Assert.Equal(false, expect);
         }
 
         [Theory]
@@ -56,4 +53,4 @@ namespace Masuit.Tools.Test
             Xunit.Assert.True(phone.MatchLandline());
         }
     }
-}
+}

+ 6 - 15
Test/Masuit.Tools.Test/Masuit.Tools.Test.csproj

@@ -97,15 +97,6 @@
     <PackageReference Include="Moq">
       <Version>4.20.70</Version>
     </PackageReference>
-    <PackageReference Include="MSTest.TestAdapter">
-      <Version>3.2.0</Version>
-    </PackageReference>
-    <PackageReference Include="MSTest.TestFramework">
-      <Version>3.2.0</Version>
-    </PackageReference>
-    <PackageReference Include="NUnit">
-      <Version>4.0.1</Version>
-    </PackageReference>
     <PackageReference Include="System.Runtime.CompilerServices.Unsafe">
       <Version>6.0.0</Version>
     </PackageReference>
@@ -116,25 +107,25 @@
       <Version>4.5.0</Version>
     </PackageReference>
     <PackageReference Include="xunit">
-      <Version>2.6.6</Version>
+      <Version>2.7.0</Version>
     </PackageReference>
     <PackageReference Include="xunit.abstractions">
       <Version>2.0.3</Version>
     </PackageReference>
     <PackageReference Include="xunit.analyzers">
-      <Version>1.10.0</Version>
+      <Version>1.11.0</Version>
     </PackageReference>
     <PackageReference Include="xunit.assert">
-      <Version>2.6.6</Version>
+      <Version>2.7.0</Version>
     </PackageReference>
     <PackageReference Include="xunit.core">
-      <Version>2.6.6</Version>
+      <Version>2.7.0</Version>
     </PackageReference>
     <PackageReference Include="xunit.extensibility.core">
-      <Version>2.6.6</Version>
+      <Version>2.7.0</Version>
     </PackageReference>
     <PackageReference Include="xunit.extensibility.execution">
-      <Version>2.6.6</Version>
+      <Version>2.7.0</Version>
     </PackageReference>
   </ItemGroup>
   <Import Project="$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets" Condition="Exists('$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets')" />

+ 0 - 8
Test/Masuit.Tools.Test/Mvc/BaseTests.cs

@@ -1,6 +1,5 @@
 using Masuit.Tools.Test.Mvc.Mocks;
 using Moq;
-using NUnit.Framework;
 using System;
 using System.IO;
 using System.Web;
@@ -9,7 +8,6 @@ using System.Web.Routing;
 
 namespace Masuit.Tools.Test.Mvc
 {
-    [TestFixture]
     public abstract class BaseTests
     {
         protected internal MockHttpResponse Response { get; set; }
@@ -37,12 +35,6 @@ namespace Masuit.Tools.Test.Mvc
             InitMocks();
         }
 
-        [SetUp]
-        public void BaseTestsSetup()
-        {
-            InitMocks();
-        }
-
         protected void InitMocks()
         {
             var mockHttpContext = new Mock<HttpContextBase>();

+ 25 - 27
Test/Masuit.Tools.Test/Mvc/MimeMapperTests.cs

@@ -1,59 +1,57 @@
 // ReSharper disable InconsistentNaming
 
 using Masuit.Tools.Mime;
-using NUnit.Framework;
+using Xunit;
 
 namespace Masuit.Tools.UnitTest.Mvc
 {
-    [TestFixture]
     public class MimeMapperTests
     {
         private IMimeMapper _mapper;
 
-        [SetUp]
-        public void Setup()
+        public MimeMapperTests()
         {
             _mapper = new MimeMapper();
         }
 
-        [Test]
+        [Fact]
         public void GetDefaultExtension()
         {
-            Assert.AreEqual("text/plain", _mapper.GetMimeFromExtension("txt"));
+            Assert.Equal("text/plain", _mapper.GetMimeFromExtension("txt"));
         }
 
-        [Test]
+        [Fact]
         public void Search_Works_For_Extensions_With_Dot_As_Well()
         {
-            Assert.IsNotNull(_mapper.GetMimeFromExtension("css"));
-            Assert.AreEqual(_mapper.GetMimeFromExtension("css"), _mapper.GetMimeFromExtension(".css"));
+            Assert.NotNull(_mapper.GetMimeFromExtension("css"));
+            Assert.Equal(_mapper.GetMimeFromExtension("css"), _mapper.GetMimeFromExtension(".css"));
         }
 
-        [Test]
+        [Fact]
         public void It_Returns_Default_Mime_For_Null_In_Extension()
         {
-            Assert.AreEqual("application/octet-stream", _mapper.GetMimeFromExtension(null));
+            Assert.Equal("application/octet-stream", _mapper.GetMimeFromExtension(null));
         }
 
-        [Test]
+        [Fact]
         public void It_Returns_Default_Mime_For_Not_Found_Extension()
         {
-            Assert.AreEqual("application/octet-stream", _mapper.GetMimeFromExtension("not found"));
+            Assert.Equal("application/octet-stream", _mapper.GetMimeFromExtension("not found"));
         }
 
-        [Test]
+        [Fact]
         public void It_Searches_In_Full_Path()
         {
-            Assert.AreEqual("image/gif", _mapper.GetMimeFromPath("C:\\folder1\\folder2\\text.gif"));
+            Assert.Equal("image/gif", _mapper.GetMimeFromPath("C:\\folder1\\folder2\\text.gif"));
         }
 
-        [Test]
+        [Fact]
         public void It_Searches_In_Relative_Path()
         {
-            Assert.AreEqual("image/gif", _mapper.GetMimeFromPath("..\\..\\..\\text.gif"));
+            Assert.Equal("image/gif", _mapper.GetMimeFromPath("..\\..\\..\\text.gif"));
         }
 
-        [Test]
+        [Fact]
         public void Extension_Overrides_Default_Mime()
         {
             _mapper = new MimeMapper(new MimeMappingItem
@@ -61,22 +59,22 @@ namespace Masuit.Tools.UnitTest.Mvc
                 Extension = "txt",
                 MimeType = "my own mime type"
             });
-            Assert.AreEqual("my own mime type", _mapper.GetMimeFromPath(".txt"));
-            Assert.AreEqual("my own mime type", _mapper.GetMimeFromPath("..\\..\\..\\text.txt"));
+            Assert.Equal("my own mime type", _mapper.GetMimeFromPath(".txt"));
+            Assert.Equal("my own mime type", _mapper.GetMimeFromPath("..\\..\\..\\text.txt"));
         }
 
-        [Test]
+        [Fact]
         public void Search_Works_For_Files_With_Dots_In_Name()
         {
-            Assert.AreEqual("text/javascript", _mapper.GetMimeFromPath("jquery.min.js"));
-            Assert.AreEqual("text/javascript", _mapper.GetMimeFromPath("http://example.com/jquery.min.js"));
+            Assert.Equal("text/javascript", _mapper.GetMimeFromPath("jquery.min.js"));
+            Assert.Equal("text/javascript", _mapper.GetMimeFromPath("http://example.com/jquery.min.js"));
         }
 
-        [Test]
+        [Fact]
         public void It_Returns_Default_Mime_For_Files_Without_Extension()
         {
-            Assert.AreEqual("application/octet-stream", _mapper.GetMimeFromPath("testfile"));
-            Assert.AreEqual("application/octet-stream", _mapper.GetMimeFromPath("\\\\network\\share\\testfile"));
+            Assert.Equal("application/octet-stream", _mapper.GetMimeFromPath("testfile"));
+            Assert.Equal("application/octet-stream", _mapper.GetMimeFromPath("\\\\network\\share\\testfile"));
         }
     }
-}
+}

+ 155 - 157
Test/Masuit.Tools.Test/Mvc/ResumeFileResultTests.cs

@@ -1,22 +1,20 @@
 using Masuit.Tools.Mvc;
 using Masuit.Tools.Mvc.ActionResults;
 using Masuit.Tools.Test.Mvc.Mocks;
-using NUnit.Framework;
 using System;
 using System.IO;
 using System.Net;
 using System.Threading;
+using Xunit;
 
 namespace Masuit.Tools.Test.Mvc
 {
-    [TestFixture]
     public class ResumeFileResultTests : BaseTests
     {
         private FileInfo _file;
         private FileInfo _file2;
 
-        [SetUp]
-        public void Setup()
+        public ResumeFileResultTests()
         {
             _file = new FileInfo(FilePath("download-test-file.txt"));
             _file2 = new FileInfo(FilePath("download-test-file2.txt"));
@@ -24,456 +22,456 @@ namespace Masuit.Tools.Test.Mvc
             Response.ClearTestResponse();
         }
 
-        [Test]
+        [Fact]
         public void CanCalculateEtagForFile()
         {
-            Assert.IsNotNull(ResumeFileResult.Util.Etag(_file));
+            Assert.NotNull(ResumeFileResult.Util.Etag(_file));
         }
 
-        [Test]
+        [Fact]
         public void EtagDoesNotDependOnTime()
         {
             var etag1 = ResumeFileResult.Util.Etag(_file);
             Thread.Sleep(100);
             var etag2 = ResumeFileResult.Util.Etag(_file);
-            Assert.AreEqual(etag1, etag2);
+            Assert.Equal(etag1, etag2);
         }
 
-        [Test]
+        [Fact]
         public void EtagDoesDependOnFile()
         {
             var etag1 = ResumeFileResult.Util.Etag(_file);
             Thread.Sleep(100);
             var etag2 = ResumeFileResult.Util.Etag(_file2);
-            Assert.AreNotEqual(etag1, etag2);
+            Assert.NotEqual(etag1, etag2);
         }
 
-        [Test]
+        [Fact]
         public void IsNotModified_Is_False_If_IfNoneMatch_And_IfModifiedSince_Are_Empty()
         {
             Request.Headers[HttpHeaders.IfNoneMatch] = null;
             Request.Headers[HttpHeaders.IfModifiedSince] = null;
-            Assert.IsFalse(new MockResumeFileResult(_file.FullName, Request).IsNotModified());
+            Assert.False(new MockResumeFileResult(_file.FullName, Request).IsNotModified());
         }
 
-        [Test]
+        [Fact]
         public void IsNotModified_Is_False_If_Etag_Is_Invalid_And_IfModifiedSince_Is_Null()
         {
             var etag = "invalid etag";
             Request.Headers[HttpHeaders.IfNoneMatch] = etag;
             Request.Headers[HttpHeaders.IfModifiedSince] = null;
-            Assert.IsFalse(new MockResumeFileResult(_file.FullName, Request).IsNotModified());
+            Assert.False(new MockResumeFileResult(_file.FullName, Request).IsNotModified());
         }
 
-        [Test]
+        [Fact]
         public void IsNotModified_Is_True_If_Etag_Is_Valid()
         {
             var etag = ResumeFileResult.Util.Etag(_file);
             Request.Headers[HttpHeaders.IfNoneMatch] = etag;
-            Assert.IsTrue(new MockResumeFileResult(_file.FullName, Request).IsNotModified());
+            Assert.True(new MockResumeFileResult(_file.FullName, Request).IsNotModified());
         }
 
-        [Test]
+        [Fact]
         public void IsNotModified_Is_True_If_Etag_Is_Star()
         {
             var etag = "*";
             Request.Headers[HttpHeaders.IfNoneMatch] = etag;
-            Assert.IsTrue(new MockResumeFileResult(_file.FullName, Request).IsNotModified());
+            Assert.True(new MockResumeFileResult(_file.FullName, Request).IsNotModified());
         }
 
-        [Test]
+        [Fact]
         public void IsNotModified_Is_False_If_Etag_Is_Empty_And_IfModifiedSince_Is_Invalid()
         {
             Request.Headers[HttpHeaders.IfModifiedSince] = DateTime.Now.ToString("R");
-            Assert.IsFalse(new MockResumeFileResult(_file.FullName, Request).IsNotModified());
+            Assert.False(new MockResumeFileResult(_file.FullName, Request).IsNotModified());
         }
 
-        [Test]
+        [Fact]
         public void IsNotModified_Is_False_If_Etag_Is_Empty_And_IfModifiedSince_Is_LastFileWriteTime()
         {
             Request.Headers[HttpHeaders.IfModifiedSince] = _file.LastWriteTime.ToString("R");
-            Assert.IsTrue(new MockResumeFileResult(_file.FullName, Request).IsNotModified());
+            Assert.True(new MockResumeFileResult(_file.FullName, Request).IsNotModified());
         }
 
-        [Test]
+        [Fact]
         public void IsPreconditionFailedTest_Is_False_If_ifMatch_And_ifUnmodifiedSince_Are_Empty()
         {
             Request.Headers[HttpHeaders.IfMatch] = null;
             Request.Headers[HttpHeaders.IfUnmodifiedSince] = null;
-            Assert.IsFalse(new MockResumeFileResult(_file.FullName, Request).IsPreconditionFailed());
+            Assert.False(new MockResumeFileResult(_file.FullName, Request).IsPreconditionFailed());
         }
 
-        [Test]
-        public void IsPreconditionFailedTest_Is_IsTrue_If_ifMatch_Doesnot_Match_Etag_Of_The_File()
+        [Fact]
+        public void IsPreconditionFailedTest_Is_True_If_ifMatch_Doesnot_Match_Etag_Of_The_File()
         {
             Request.Headers[HttpHeaders.IfMatch] = "incorrect";
-            Assert.IsTrue(new MockResumeFileResult(_file.FullName, Request).IsPreconditionFailed());
+            Assert.True(new MockResumeFileResult(_file.FullName, Request).IsPreconditionFailed());
         }
 
-        [Test]
-        public void IsPreconditionFailedTest_Is_IsFalse_If_ifMatch_Matches_Etag_Of_The_File()
+        [Fact]
+        public void IsPreconditionFailedTest_Is_False_If_ifMatch_Matches_Etag_Of_The_File()
         {
             Request.Headers[HttpHeaders.IfMatch] = ResumeFileResult.Util.Etag(_file);
-            Assert.IsFalse(new MockResumeFileResult(_file.FullName, Request).IsPreconditionFailed());
+            Assert.False(new MockResumeFileResult(_file.FullName, Request).IsPreconditionFailed());
         }
 
-        [Test]
-        public void IsPreconditionFailedTest_Is_IsFalse_If_ifMatch_Equals_Star()
+        [Fact]
+        public void IsPreconditionFailedTest_Is_False_If_ifMatch_Equals_Star()
         {
             Request.Headers[HttpHeaders.IfMatch] = "*";
-            Assert.IsFalse(new MockResumeFileResult(_file.FullName, Request).IsPreconditionFailed());
+            Assert.False(new MockResumeFileResult(_file.FullName, Request).IsPreconditionFailed());
         }
 
-        [Test]
-        public void IsPreconditionFailedTest_Is_IsTrue_If_ifUnmodifiedSince_Doesnot_Equal_FileLastWriteTime()
+        [Fact]
+        public void IsPreconditionFailedTest_Is_True_If_ifUnmodifiedSince_Doesnot_Equal_FileLastWriteTime()
         {
             Request.Headers[HttpHeaders.IfUnmodifiedSince] = DateTime.Now.ToString("R");
-            Assert.IsTrue(new MockResumeFileResult(_file.FullName, Request).IsPreconditionFailed());
+            Assert.True(new MockResumeFileResult(_file.FullName, Request).IsPreconditionFailed());
         }
 
-        [Test]
-        public void IsPreconditionFailedTest_Is_IsFalse_If_ifUnmodifiedSince_Equals_FileLastWriteTime()
+        [Fact]
+        public void IsPreconditionFailedTest_Is_False_If_ifUnmodifiedSince_Equals_FileLastWriteTime()
         {
             Request.Headers[HttpHeaders.IfUnmodifiedSince] = _file.LastWriteTime.ToString("R");
-            Assert.IsFalse(new MockResumeFileResult(_file.FullName, Request).IsPreconditionFailed());
+            Assert.False(new MockResumeFileResult(_file.FullName, Request).IsPreconditionFailed());
         }
 
-        [Test]
+        [Fact]
         public void IsRangeNotSatisfiable_Is_True_If_Range_Header_Has_Invalid_Format()
         {
             Request.Headers[HttpHeaders.Range] = "blah";
-            Assert.IsTrue(new MockResumeFileResult(_file.FullName, Request).IsRangeNotSatisfiable());
+            Assert.True(new MockResumeFileResult(_file.FullName, Request).IsRangeNotSatisfiable());
         }
 
-        [Test]
+        [Fact]
         public void IsRangeNotSatisfiable_Is_True_If_Start_Greater_Than_End()
         {
             Request.Headers[HttpHeaders.Range] = "bytes=100-0";
-            Assert.IsTrue(new MockResumeFileResult(_file.FullName, Request).IsRangeNotSatisfiable());
+            Assert.True(new MockResumeFileResult(_file.FullName, Request).IsRangeNotSatisfiable());
         }
 
-        [Test]
+        [Fact]
         public void IsRangeNotSatisfiable_Is_True_If_End_Equals_Total_File_Size()
         {
             Request.Headers[HttpHeaders.Range] = "bytes=0-" + _file.Length;
-            Assert.IsTrue(new MockResumeFileResult(_file.FullName, Request).IsRangeNotSatisfiable());
+            Assert.True(new MockResumeFileResult(_file.FullName, Request).IsRangeNotSatisfiable());
         }
 
-        [Test]
+        [Fact]
         public void IsRangeNotSatisfiable_Is_True_If_End_Greater_Than_Total_File_Size()
         {
             Request.Headers[HttpHeaders.Range] = "bytes=0-" + _file.Length + 10;
-            Assert.IsTrue(new MockResumeFileResult(_file.FullName, Request).IsRangeNotSatisfiable());
+            Assert.True(new MockResumeFileResult(_file.FullName, Request).IsRangeNotSatisfiable());
         }
 
-        [Test]
+        [Fact]
         public void IsRangeNotSatisfiable_Is_False_If_Range_Header_Is_Null()
         {
             Request.Headers[HttpHeaders.Range] = null;
-            Assert.IsFalse(new MockResumeFileResult(_file.FullName, Request).IsRangeNotSatisfiable());
+            Assert.False(new MockResumeFileResult(_file.FullName, Request).IsRangeNotSatisfiable());
         }
 
-        [Test]
+        [Fact]
         public void IsRangeNotSatisfiable_Is_False_If_Range_Has_StartsWith_Format()
         {
             Request.Headers[HttpHeaders.Range] = "bytes=0-";
-            Assert.IsFalse(new MockResumeFileResult(_file.FullName, Request).IsRangeNotSatisfiable());
+            Assert.False(new MockResumeFileResult(_file.FullName, Request).IsRangeNotSatisfiable());
         }
 
-        [Test]
+        [Fact]
         public void IsRangeNotSatisfiable_Is_False_If_Range_Has_LastXbytes_Format()
         {
             Request.Headers[HttpHeaders.Range] = "bytes=-100";
-            Assert.IsFalse(new MockResumeFileResult(_file.FullName, Request).IsRangeNotSatisfiable());
+            Assert.False(new MockResumeFileResult(_file.FullName, Request).IsRangeNotSatisfiable());
         }
 
-        [Test]
+        [Fact]
         public void IsRangeNotSatisfiable_Is_False_If_Range_Ends_With_Last_Byte_Position()
         {
             Request.Headers[HttpHeaders.Range] = "bytes=100-" + (_file.Length - 1);
-            Assert.IsFalse(new MockResumeFileResult(_file.FullName, Request).IsRangeNotSatisfiable());
+            Assert.False(new MockResumeFileResult(_file.FullName, Request).IsRangeNotSatisfiable());
         }
 
-        [Test]
+        [Fact]
         public void SendRange_Is_False_If_Range_And_ifRange_Headers_Are_Null()
         {
-            Assert.IsFalse(new MockResumeFileResult(_file.FullName, Request).SendRange());
+            Assert.False(new MockResumeFileResult(_file.FullName, Request).SendRange());
         }
 
-        [Test]
+        [Fact]
         public void SendRange_Is_False_If_Range_Is_Null_And_ifRange_Is_Correct()
         {
             Request.Headers[HttpHeaders.IfRange] = ResumeFileResult.Util.Etag(_file);
-            Assert.IsFalse(new MockResumeFileResult(_file.FullName, Request).SendRange());
+            Assert.False(new MockResumeFileResult(_file.FullName, Request).SendRange());
         }
 
-        [Test]
+        [Fact]
         public void SendRange_Is_True_If_Range_Is_Correct_And_ifRange_Is_Null()
         {
             Request.Headers[HttpHeaders.Range] = "bytes=0-100";
-            Assert.IsTrue(new MockResumeFileResult(_file.FullName, Request).SendRange());
+            Assert.True(new MockResumeFileResult(_file.FullName, Request).SendRange());
         }
 
-        [Test]
+        [Fact]
         public void SendRange_Is_True_If_Range_And_ifRange_Are_Correct()
         {
             Request.Headers[HttpHeaders.IfRange] = ResumeFileResult.Util.Etag(_file);
             Request.Headers[HttpHeaders.Range] = "bytes=0-100";
-            Assert.IsTrue(new MockResumeFileResult(_file.FullName, Request).SendRange());
+            Assert.True(new MockResumeFileResult(_file.FullName, Request).SendRange());
         }
 
-        [Test]
+        [Fact]
         public void SendRange_Is_False_If_Range_Is_Correct_But_ifRange_Is_InCorrect()
         {
             Request.Headers[HttpHeaders.IfRange] = "incorrect etag";
             Request.Headers[HttpHeaders.Range] = "bytes=0-100";
-            Assert.IsFalse(new MockResumeFileResult(_file.FullName, Request).SendRange());
+            Assert.False(new MockResumeFileResult(_file.FullName, Request).SendRange());
         }
 
-        [Test]
+        [Fact]
         public void HeadersTest_Should_Not_Send_File_If_File_Has_Not_Been_Changed()
         {
             Request.Headers[HttpHeaders.IfNoneMatch] = ResumeFileResult.Util.Etag(_file);
             var result = new MockResumeFileResult(_file.FullName, Request);
-            Assert.IsTrue(result.IsNotModified());
+            Assert.True(result.IsNotModified());
             result.WriteFileTest(Response);
-            Assert.AreEqual((int)HttpStatusCode.NotModified, Response.StatusCode);
-            Assert.IsNotNull(Response.Headers[HttpHeaders.Etag]);
-            Assert.IsNotNull(Response.Headers[HttpHeaders.Expires]);
-            Assert.IsNotNull(Response.Headers[HttpHeaders.LastModified]);
-            Assert.IsNull(Response.Headers[HttpHeaders.ContentRange]);
-            Assert.AreEqual(0, Response.OutputStream.Length);
+            Assert.Equal((int)HttpStatusCode.NotModified, Response.StatusCode);
+            Assert.NotNull(Response.Headers[HttpHeaders.Etag]);
+            Assert.NotNull(Response.Headers[HttpHeaders.Expires]);
+            Assert.NotNull(Response.Headers[HttpHeaders.LastModified]);
+            Assert.Null(Response.Headers[HttpHeaders.ContentRange]);
+            Assert.Equal(0, Response.OutputStream.Length);
         }
 
-        [Test]
+        [Fact]
         public void HeadersTest_Should_Not_Send_File_IfPreconditionFailed()
         {
             Request.Headers[HttpHeaders.IfMatch] = "invalid";
             var result = new MockResumeFileResult(_file.FullName, Request);
-            Assert.IsTrue(result.IsPreconditionFailed());
+            Assert.True(result.IsPreconditionFailed());
 
             result.WriteFileTest(Response);
-            Assert.AreEqual((int)HttpStatusCode.PreconditionFailed, Response.StatusCode);
-            Assert.IsNotNull(Response.Headers[HttpHeaders.Etag]);
-            Assert.IsNotNull(Response.Headers[HttpHeaders.Expires]);
-            Assert.IsNotNull(Response.Headers[HttpHeaders.LastModified]);
-            Assert.IsNull(Response.Headers[HttpHeaders.ContentRange]);
-            Assert.AreEqual(0, Response.OutputStream.Length);
+            Assert.Equal((int)HttpStatusCode.PreconditionFailed, Response.StatusCode);
+            Assert.NotNull(Response.Headers[HttpHeaders.Etag]);
+            Assert.NotNull(Response.Headers[HttpHeaders.Expires]);
+            Assert.NotNull(Response.Headers[HttpHeaders.LastModified]);
+            Assert.Null(Response.Headers[HttpHeaders.ContentRange]);
+            Assert.Equal(0, Response.OutputStream.Length);
         }
 
-        [Test]
+        [Fact]
         public void HeadersTest_Should_Not_Send_File_Is_RangeNotSatisfiable()
         {
             Request.Headers[HttpHeaders.Range] = "invalid";
             var result = new MockResumeFileResult(_file.FullName, Request);
-            Assert.IsTrue(result.IsRangeNotSatisfiable());
+            Assert.True(result.IsRangeNotSatisfiable());
             result.WriteFileTest(Response);
-            Assert.AreEqual((int)HttpStatusCode.RequestedRangeNotSatisfiable, Response.StatusCode);
-            Assert.IsNotNull(Response.Headers[HttpHeaders.Etag]);
-            Assert.IsNotNull(Response.Headers[HttpHeaders.Expires]);
-            Assert.IsNotNull(Response.Headers[HttpHeaders.LastModified]);
-            Assert.AreEqual("bytes */" + _file.Length, Response.Headers[HttpHeaders.ContentRange]);
-            Assert.AreEqual(0, Response.OutputStream.Length);
+            Assert.Equal((int)HttpStatusCode.RequestedRangeNotSatisfiable, Response.StatusCode);
+            Assert.NotNull(Response.Headers[HttpHeaders.Etag]);
+            Assert.NotNull(Response.Headers[HttpHeaders.Expires]);
+            Assert.NotNull(Response.Headers[HttpHeaders.LastModified]);
+            Assert.Equal("bytes */" + _file.Length, Response.Headers[HttpHeaders.ContentRange]);
+            Assert.Equal(0, Response.OutputStream.Length);
         }
 
-        [Test]
+        [Fact]
         public void HeadersTest_Should_Send_File_If_All_Headers_Are_Null()
         {
             var result = new MockResumeFileResult(_file.FullName, Request);
             result.WriteFileTest(Response);
-            Assert.AreEqual((int)HttpStatusCode.OK, Response.StatusCode);
-            Assert.IsNotNull(Response.Headers[HttpHeaders.Etag]);
-            Assert.IsNotNull(Response.Headers[HttpHeaders.Expires]);
-            Assert.IsNotNull(Response.Headers[HttpHeaders.LastModified]);
-            Assert.IsNotNull(Response.Headers[HttpHeaders.ContentRange]);
-            Assert.IsNotNull(Response.Headers[HttpHeaders.ContentLength]);
-            Assert.AreEqual(_file.Length, Response.OutputStream.Length);
+            Assert.Equal((int)HttpStatusCode.OK, Response.StatusCode);
+            Assert.NotNull(Response.Headers[HttpHeaders.Etag]);
+            Assert.NotNull(Response.Headers[HttpHeaders.Expires]);
+            Assert.NotNull(Response.Headers[HttpHeaders.LastModified]);
+            Assert.NotNull(Response.Headers[HttpHeaders.ContentRange]);
+            Assert.NotNull(Response.Headers[HttpHeaders.ContentLength]);
+            Assert.Equal(_file.Length, Response.OutputStream.Length);
         }
 
-        [Test]
+        [Fact]
         public void Range_First_500b()
         {
             var stream = GetResponseStream("bytes=0-499");
-            Assert.AreEqual(500, stream.Length);
-            Assert.AreEqual(206, Response.StatusCode);
-            Assert.AreEqual($"bytes 0-499/{_file.Length}", Response.Headers[HttpHeaders.ContentRange]);
+            Assert.Equal(500, stream.Length);
+            Assert.Equal(206, Response.StatusCode);
+            Assert.Equal($"bytes 0-499/{_file.Length}", Response.Headers[HttpHeaders.ContentRange]);
         }
 
-        [Test]
+        [Fact]
         public void Range_From_500b_to_899b()
         {
             var stream = GetResponseStream("bytes=500-899");
-            Assert.AreEqual(400, stream.Length);
-            Assert.AreEqual(206, Response.StatusCode);
-            Assert.AreEqual($"bytes 500-899/{_file.Length}", Response.Headers[HttpHeaders.ContentRange]);
+            Assert.Equal(400, stream.Length);
+            Assert.Equal(206, Response.StatusCode);
+            Assert.Equal($"bytes 500-899/{_file.Length}", Response.Headers[HttpHeaders.ContentRange]);
         }
 
-        [Test]
+        [Fact]
         public void Range_Last_300b()
         {
             var stream = GetResponseStream("bytes=-300");
-            Assert.AreEqual(300, stream.Length);
-            Assert.AreEqual(206, Response.StatusCode);
+            Assert.Equal(300, stream.Length);
+            Assert.Equal(206, Response.StatusCode);
             var from = _file.Length - 300;
             var to = _file.Length - 1;
 
-            Assert.AreEqual($"bytes {from}-{to}/{_file.Length}", Response.Headers[HttpHeaders.ContentRange]);
+            Assert.Equal($"bytes {from}-{to}/{_file.Length}", Response.Headers[HttpHeaders.ContentRange]);
         }
 
-        [Test]
+        [Fact]
         public void Range_From_100b_toThe_End()
         {
             var stream = GetResponseStream($"bytes={(_file.Length - 100)}-");
-            Assert.AreEqual(100, stream.Length);
-            Assert.AreEqual(206, Response.StatusCode);
+            Assert.Equal(100, stream.Length);
+            Assert.Equal(206, Response.StatusCode);
             var from = _file.Length - 100;
             var to = _file.Length - 1;
-            Assert.AreEqual($"bytes {from}-{to}/{_file.Length}", Response.Headers[HttpHeaders.ContentRange]);
+            Assert.Equal($"bytes {from}-{to}/{_file.Length}", Response.Headers[HttpHeaders.ContentRange]);
         }
 
-        [Test]
+        [Fact]
         public void Range_First_1b()
         {
             var stream = GetResponseStream("bytes=0-0");
-            Assert.AreEqual(1, stream.Length);
-            Assert.AreEqual(206, Response.StatusCode);
-            Assert.AreEqual($"bytes 0-0/{_file.Length}", Response.Headers[HttpHeaders.ContentRange]);
+            Assert.Equal(1, stream.Length);
+            Assert.Equal(206, Response.StatusCode);
+            Assert.Equal($"bytes 0-0/{_file.Length}", Response.Headers[HttpHeaders.ContentRange]);
         }
 
-        [Test]
+        [Fact]
         public void Range_Last_1b()
         {
             var stream = GetResponseStream("bytes=-1");
-            Assert.AreEqual(1, stream.Length);
-            Assert.AreEqual(206, Response.StatusCode);
+            Assert.Equal(1, stream.Length);
+            Assert.Equal(206, Response.StatusCode);
             var from = _file.Length - 1;
             var to = _file.Length - 1;
-            Assert.AreEqual($"bytes {from}-{to}/{_file.Length}", Response.Headers[HttpHeaders.ContentRange]);
+            Assert.Equal($"bytes {from}-{to}/{_file.Length}", Response.Headers[HttpHeaders.ContentRange]);
         }
 
-        [Test]
+        [Fact]
         public void Range_Whole_File_With_RangeHeader()
         {
             var stream = GetResponseStream("bytes=0-" + (_file.Length - 1));
-            Assert.AreEqual(_file.Length, stream.Length);
-            Assert.AreEqual(206, Response.StatusCode);
-            Assert.AreEqual($"bytes 0-{(_file.Length - 1)}/{_file.Length}", Response.Headers[HttpHeaders.ContentRange]);
+            Assert.Equal(_file.Length, stream.Length);
+            Assert.Equal(206, Response.StatusCode);
+            Assert.Equal($"bytes 0-{(_file.Length - 1)}/{_file.Length}", Response.Headers[HttpHeaders.ContentRange]);
         }
 
-        [Test]
+        [Fact]
         public void Range_Whole_File_Without_RangeHeader()
         {
             var stream = GetResponseStream(null);
-            Assert.AreEqual(_file.Length, stream.Length);
-            Assert.AreEqual(200, Response.StatusCode);
-            Assert.AreEqual($"bytes 0-{(_file.Length - 1)}/{_file.Length}", Response.Headers[HttpHeaders.ContentRange]);
+            Assert.Equal(_file.Length, stream.Length);
+            Assert.Equal(200, Response.StatusCode);
+            Assert.Equal($"bytes 0-{(_file.Length - 1)}/{_file.Length}", Response.Headers[HttpHeaders.ContentRange]);
         }
 
-        [Test]
+        [Fact]
         public void TransmissionRange_From_0_To_0()
         {
             Request.Headers[HttpHeaders.Range] = "bytes=0-0";
             new MockResumeFileResult(_file.FullName, Request).WriteFileTest(Response);
 
-            Assert.AreEqual(1, Response.OutputStream.Length);
+            Assert.Equal(1, Response.OutputStream.Length);
             AssertBytes(_file, Response.OutputStream, 0, 1);
         }
 
-        [Test]
+        [Fact]
         public void TransmissionRange_From_1_To_100()
         {
             Request.Headers[HttpHeaders.Range] = "bytes=1-100";
             new MockResumeFileResult(_file.FullName, Request).WriteFileTest(Response);
 
-            Assert.AreEqual(100, Response.OutputStream.Length);
+            Assert.Equal(100, Response.OutputStream.Length);
             AssertBytes(_file, Response.OutputStream, 1, 100);
         }
 
-        [Test]
+        [Fact]
         public void TransmissionRange_From_101_To_theEnd()
         {
             Request.Headers[HttpHeaders.Range] = "bytes=101-";
             new MockResumeFileResult(_file.FullName, Request).WriteFileTest(Response);
 
-            Assert.AreEqual(_file.Length - 101, Response.OutputStream.Length);
+            Assert.Equal(_file.Length - 101, Response.OutputStream.Length);
             AssertBytes(_file, Response.OutputStream, 101, (int)_file.Length);
         }
 
-        [Test]
+        [Fact]
         public void TransmissionRange_WholeFile_WithRangeHeader()
         {
             Request.Headers[HttpHeaders.Range] = "bytes=0-";
             new MockResumeFileResult(_file.FullName, Request).WriteFileTest(Response);
 
-            Assert.AreEqual(_file.Length, Response.OutputStream.Length);
+            Assert.Equal(_file.Length, Response.OutputStream.Length);
             AssertBytes(_file, Response.OutputStream, 0, (int)_file.Length);
         }
 
-        [Test]
+        [Fact]
         public void TransmissionRange_WholeFile_WithoutRangeHeader()
         {
             Request.Headers[HttpHeaders.Range] = null;
             new MockResumeFileResult(_file.FullName, Request).WriteFileTest(Response);
 
-            Assert.AreEqual(_file.Length, Response.OutputStream.Length);
+            Assert.Equal(_file.Length, Response.OutputStream.Length);
             AssertBytes(_file, Response.OutputStream, 0, (int)_file.Length);
         }
 
-        [Test]
+        [Fact]
         public void ShouldSend206If_Range_HeaderExists()
         {
             Request.Headers[HttpHeaders.Range] = "bytes=0-";
             new MockResumeFileResult(_file.FullName, Request).WriteFileTest(Response);
-            Assert.AreEqual(206, Response.StatusCode);
+            Assert.Equal(206, Response.StatusCode);
         }
 
-        [Test]
+        [Fact]
         public void ShouldSend200If_Range_HeaderDoesNotExist()
         {
             Request.Headers[HttpHeaders.Range] = null;
             new MockResumeFileResult(_file.FullName, Request).WriteFileTest(Response);
-            Assert.AreEqual(200, Response.StatusCode);
+            Assert.Equal(200, Response.StatusCode);
         }
 
-        [Test]
+        [Fact]
         public void IfRangeHeader_Should_Be_Ignored_If_ItNotEquals_Etag()
         {
             Request.Headers[HttpHeaders.IfRange] = "ifRange fake header";
             var mock = new MockResumeFileResult(_file.FullName, Request);
             mock.WriteFileTest(Response);
 
-            Assert.AreNotEqual(ResumeFileResult.Util.Etag(_file), Request.Headers[HttpHeaders.IfRange]);
-            Assert.AreEqual(200, Response.StatusCode);
+            Assert.NotEqual(ResumeFileResult.Util.Etag(_file), Request.Headers[HttpHeaders.IfRange]);
+            Assert.Equal(200, Response.StatusCode);
         }
 
-        [Test]
+        [Fact]
         public void Etag_Should_Be_Added_To_Response_If_It_Equals_With_IfRange_In_Request()
         {
             var etag = ResumeFileResult.Util.Etag(_file);
             Request.Headers[HttpHeaders.IfRange] = etag;
             var mock = new MockResumeFileResult(_file.FullName, Request);
             mock.WriteFileTest(Response);
-            Assert.AreEqual(Response.Headers[HttpHeaders.Etag], etag);
-            Assert.AreEqual(200, Response.StatusCode);
+            Assert.Equal(Response.Headers[HttpHeaders.Etag], etag);
+            Assert.Equal(200, Response.StatusCode);
         }
 
-        [Test]
+        [Fact]
         public void Etag_Should_Be_Added_To_Response_If_It_Equals_With_IfRange_In_Request__PartialResponse()
         {
             var etag = ResumeFileResult.Util.Etag(_file);
             Request.Headers[HttpHeaders.IfRange] = etag;
             Request.Headers[HttpHeaders.Range] = "bytes=0-";
             new MockResumeFileResult(_file.FullName, Request).WriteFileTest(Response);
-            Assert.AreEqual(Response.Headers[HttpHeaders.Etag], etag);
-            Assert.IsNotNull(Response.Headers[HttpHeaders.ContentRange]);
-            Assert.AreEqual(206, Response.StatusCode);
+            Assert.Equal(Response.Headers[HttpHeaders.Etag], etag);
+            Assert.NotNull(Response.Headers[HttpHeaders.ContentRange]);
+            Assert.Equal(206, Response.StatusCode);
         }
 
-        [Test]
+        [Fact]
         public void It_Should_Attach_Content_Disposition_If_There_Is_Download_File_Name()
         {
             new MockResumeFileResult(_file.FullName, Request, "test.name").WriteFileTest(Response);
-            Assert.IsNotNull(Response.Headers[HttpHeaders.ContentDisposition]);
+            Assert.NotNull(Response.Headers[HttpHeaders.ContentDisposition]);
         }
 
         private Stream GetResponseStream(string range)
@@ -493,11 +491,11 @@ namespace Masuit.Tools.Test.Mvc
             {
                 responseStream.Seek(0, SeekOrigin.Begin);
                 fileStream.Seek(from, SeekOrigin.Begin);
-                for (var byteIndex = from ; byteIndex < to ; byteIndex++)
+                for (var byteIndex = from; byteIndex < to; byteIndex++)
                 {
                     var responseByte = responseStream.ReadByte();
                     var fileByte = fileStream.ReadByte();
-                    Assert.AreEqual(responseByte, fileByte);
+                    Assert.Equal(responseByte, fileByte);
                 }
             }
         }

+ 8 - 10
Test/Masuit.Tools.Test/TemplateTest.cs

@@ -1,31 +1,29 @@
 using Masuit.Tools.Strings;
-using Microsoft.VisualStudio.TestTools.UnitTesting;
 using System;
-using Assert = Microsoft.VisualStudio.TestTools.UnitTesting.Assert;
+using Xunit;
 
 namespace Masuit.Tools.Test
 {
-    [TestClass]
     public class TemplateTest
     {
-        [TestMethod]
+        [Fact]
         public void Render_Template()
         {
             var tmp = new Template("{{name}},你好!");
             tmp.Set("name", "万金油");
             string s = tmp.Render();
-            Assert.AreEqual("万金油,你好!", s);
+            Assert.Equal("万金油,你好!", s);
         }
 
-        [TestMethod]
+        [Fact]
         public void Render_TemplateWithMultiVariables()
         {
             var tmp = new Template("{{one}},{{two}},{{three}}");
             string s = tmp.Set("one", "1").Set("two", "2").Set("three", "3").Render();
-            Assert.AreEqual("1,2,3", s);
+            Assert.Equal("1,2,3", s);
         }
 
-        [TestMethod]
+        [Fact]
         public void Render_TemplateWithUncoverVariable()
         {
             var tmp = new Template("{{name}},{{greet}}!");
@@ -36,8 +34,8 @@ namespace Masuit.Tools.Test
             }
             catch (Exception e)
             {
-                Assert.IsInstanceOfType(e, typeof(ArgumentException));
-                Assert.AreEqual("模版变量{{greet}}未被使用", e.Message);
+                Assert.IsType<ArgumentException>(e);
+                Assert.Equal("模版变量{{greet}}未被使用", e.Message);
             }
         }
     }