mirror of
https://github.com/velopack/velopack.git
synced 2025-10-25 15:19:22 +00:00
Move Squirrel.Tests into it's own folder (upstream afbd349)
This commit is contained in:
527
test/Squirrel.Tests/ApplyReleasesTests.cs
Normal file
527
test/Squirrel.Tests/ApplyReleasesTests.cs
Normal file
@@ -0,0 +1,527 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using NuGet.Versioning;
|
||||
using Squirrel.NuGet;
|
||||
using Squirrel.Tests.TestHelpers;
|
||||
using Xunit;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Squirrel.Tests
|
||||
{
|
||||
public class ApplyReleasesTests : TestLoggingBase
|
||||
{
|
||||
public ApplyReleasesTests(ITestOutputHelper log) : base(log)
|
||||
{
|
||||
}
|
||||
|
||||
public const string APP_ID = "theFakeApp";
|
||||
|
||||
[Fact]
|
||||
public async Task CleanInstallRunsSquirrelAwareAppsWithInstallFlag()
|
||||
{
|
||||
using var _1 = Utility.GetTempDirectory(out var tempDir);
|
||||
using var _2 = Utility.GetTempDirectory(out var remotePkgDir);
|
||||
|
||||
IntegrationTestHelper.CreateNewVersionInPackageDir("0.1.0", remotePkgDir);
|
||||
using var fixture = UpdateManagerTestImpl.FromLocalPackageTempDir(remotePkgDir, APP_ID, tempDir);
|
||||
await fixture.FullInstall();
|
||||
|
||||
// NB: We execute the Squirrel-aware apps, so we need to give
|
||||
// them a minute to settle or else the using statement will
|
||||
// try to blow away a running process
|
||||
await Task.Delay(1000);
|
||||
|
||||
Assert.False(File.Exists(Path.Combine(tempDir, APP_ID, "current", "args2.txt")));
|
||||
Assert.True(File.Exists(Path.Combine(tempDir, APP_ID, "current", "args.txt")));
|
||||
|
||||
var text = File.ReadAllText(Path.Combine(tempDir, APP_ID, "current", "args.txt"), Encoding.UTF8);
|
||||
Assert.Contains("firstrun", text);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task UpgradeRunsSquirrelAwareAppsWithUpgradeFlag()
|
||||
{
|
||||
using var _1 = Utility.GetTempDirectory(out var tempDir);
|
||||
using var _2 = Utility.GetTempDirectory(out var remotePkgDir);
|
||||
|
||||
IntegrationTestHelper.CreateNewVersionInPackageDir("0.1.0", remotePkgDir);
|
||||
|
||||
using (var fixture = UpdateManagerTestImpl.FromLocalPackageTempDir(remotePkgDir, APP_ID, tempDir)) {
|
||||
await fixture.FullInstall();
|
||||
}
|
||||
|
||||
await Task.Delay(1000);
|
||||
|
||||
IntegrationTestHelper.CreateNewVersionInPackageDir("0.2.0", remotePkgDir);
|
||||
|
||||
using (var fixture = UpdateManagerTestImpl.FromLocalPackageTempDir(remotePkgDir, APP_ID, tempDir)) {
|
||||
await fixture.UpdateApp();
|
||||
}
|
||||
|
||||
await Task.Delay(1000);
|
||||
|
||||
Assert.False(File.Exists(Path.Combine(tempDir, APP_ID, "staging", "app-0.2.0", "args2.txt")));
|
||||
Assert.True(File.Exists(Path.Combine(tempDir, APP_ID, "staging", "app-0.2.0", "args.txt")));
|
||||
|
||||
var text = File.ReadAllText(Path.Combine(tempDir, APP_ID, "staging", "app-0.2.0", "args.txt"), Encoding.UTF8);
|
||||
Assert.Contains("updated", text);
|
||||
Assert.Contains("0.2.0", text);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task RunningUpgradeAppTwiceDoesntCrash()
|
||||
{
|
||||
using var _1 = Utility.GetTempDirectory(out var tempDir);
|
||||
using var _2 = Utility.GetTempDirectory(out var remotePkgDir);
|
||||
|
||||
IntegrationTestHelper.CreateNewVersionInPackageDir("0.1.0", remotePkgDir);
|
||||
|
||||
using (var fixture = UpdateManagerTestImpl.FromLocalPackageTempDir(remotePkgDir, APP_ID, tempDir)) {
|
||||
await fixture.FullInstall();
|
||||
}
|
||||
|
||||
await Task.Delay(1000);
|
||||
|
||||
IntegrationTestHelper.CreateNewVersionInPackageDir("0.2.0", remotePkgDir);
|
||||
|
||||
using (var fixture = UpdateManagerTestImpl.FromLocalPackageTempDir(remotePkgDir, APP_ID, tempDir)) {
|
||||
await fixture.UpdateApp();
|
||||
}
|
||||
|
||||
await Task.Delay(1000);
|
||||
|
||||
// NB: The 2nd time we won't have any updates to apply. We should just do nothing!
|
||||
using (var fixture = UpdateManagerTestImpl.FromLocalPackageTempDir(remotePkgDir, APP_ID, tempDir)) {
|
||||
await fixture.UpdateApp();
|
||||
}
|
||||
|
||||
await Task.Delay(1000);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task FullUninstallRemovesAllVersions()
|
||||
{
|
||||
using var _1 = Utility.GetTempDirectory(out var tempDir);
|
||||
using var _2 = Utility.GetTempDirectory(out var remotePkgDir);
|
||||
|
||||
IntegrationTestHelper.CreateNewVersionInPackageDir("0.1.0", remotePkgDir);
|
||||
|
||||
using (var fixture = UpdateManagerTestImpl.FromLocalPackageTempDir(remotePkgDir, APP_ID, tempDir)) {
|
||||
await fixture.FullInstall();
|
||||
}
|
||||
|
||||
await Task.Delay(1000);
|
||||
|
||||
IntegrationTestHelper.CreateNewVersionInPackageDir("0.2.0", remotePkgDir);
|
||||
|
||||
using (var fixture = UpdateManagerTestImpl.FromLocalPackageTempDir(remotePkgDir, APP_ID, tempDir)) {
|
||||
await fixture.UpdateApp();
|
||||
}
|
||||
|
||||
await Task.Delay(1000);
|
||||
|
||||
using (var fixture = UpdateManagerTestImpl.FromLocalPackageTempDir(remotePkgDir, APP_ID, tempDir)) {
|
||||
await fixture.FullUninstall();
|
||||
}
|
||||
|
||||
Assert.False(File.Exists(Path.Combine(tempDir, APP_ID, "app-0.1.0", "args.txt")));
|
||||
Assert.False(File.Exists(Path.Combine(tempDir, APP_ID, "app-0.2.0", "args.txt")));
|
||||
Assert.True(File.Exists(Path.Combine(tempDir, APP_ID, ".dead")));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task CanInstallAndUpdatePackageWithDotsInId()
|
||||
{
|
||||
string tempDir;
|
||||
string remotePkgDir;
|
||||
const string pkgName = "Squirrel.Installed.App";
|
||||
|
||||
using (Utility.GetTempDirectory(out tempDir))
|
||||
using (Utility.GetTempDirectory(out remotePkgDir)) {
|
||||
// install 0.1.0
|
||||
IntegrationTestHelper.CreateFakeInstalledApp("0.1.0", remotePkgDir, "SquirrelInstalledAppWithDots.nuspec");
|
||||
var pkgs = ReleaseEntry.BuildReleasesFile(remotePkgDir);
|
||||
ReleaseEntry.WriteReleaseFile(pkgs, Path.Combine(remotePkgDir, "RELEASES"));
|
||||
|
||||
using (var fixture = UpdateManagerTestImpl.FromLocalPackageTempDir(remotePkgDir, pkgName, tempDir)) {
|
||||
await fixture.FullInstall();
|
||||
}
|
||||
|
||||
//Assert.True(Directory.Exists(Path.Combine(tempDir, pkgName, "app-0.1.0")));
|
||||
Assert.True(Directory.Exists(Path.Combine(tempDir, pkgName, "current")));
|
||||
|
||||
var info = new AppDescWindows(Path.Combine(tempDir, pkgName), pkgName);
|
||||
|
||||
var version = info.GetVersions().Single();
|
||||
Assert.True(version.IsCurrent);
|
||||
Assert.Equal(new SemanticVersion(0, 1, 0), version.Manifest.Version);
|
||||
|
||||
await Task.Delay(1000);
|
||||
Assert.True(File.ReadAllText(Path.Combine(version.DirectoryPath, "args.txt")).Contains("--squirrel-firstrun"));
|
||||
|
||||
// update top 0.2.0
|
||||
IntegrationTestHelper.CreateFakeInstalledApp("0.2.0", remotePkgDir, "SquirrelInstalledAppWithDots.nuspec");
|
||||
pkgs = ReleaseEntry.BuildReleasesFile(remotePkgDir);
|
||||
ReleaseEntry.WriteReleaseFile(pkgs, Path.Combine(remotePkgDir, "RELEASES"));
|
||||
|
||||
using (var fixture = UpdateManagerTestImpl.FromLocalPackageTempDir(remotePkgDir, pkgName, tempDir)) {
|
||||
await fixture.UpdateApp();
|
||||
}
|
||||
|
||||
info.UpdateAndRetrieveCurrentFolder(false);
|
||||
|
||||
var versions = info.GetVersions().ToArray();
|
||||
Assert.Equal(2, versions.Count());
|
||||
Assert.Equal(new SemanticVersion(0, 2, 0), versions.Single(s => s.IsCurrent).Version);
|
||||
|
||||
//Assert.True(Directory.Exists(Path.Combine(tempDir, pkgName, "app-0.2.0")));
|
||||
await Task.Delay(1000);
|
||||
|
||||
// uninstall
|
||||
using (var fixture = UpdateManagerTestImpl.FromLocalPackageTempDir(remotePkgDir, pkgName, tempDir)) {
|
||||
await fixture.FullUninstall();
|
||||
}
|
||||
|
||||
Assert.False(File.Exists(Path.Combine(tempDir, pkgName, "app-0.1.0", "args.txt")));
|
||||
Assert.False(File.Exists(Path.Combine(tempDir, pkgName, "app-0.2.0", "args.txt")));
|
||||
Assert.True(File.Exists(Path.Combine(tempDir, pkgName, ".dead")));
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WhenNoNewReleasesAreAvailableTheListIsEmpty()
|
||||
{
|
||||
using var _ = Utility.GetTempDirectory(out var tempDir);
|
||||
|
||||
var appDir = Directory.CreateDirectory(Path.Combine(tempDir, APP_ID));
|
||||
var packages = Path.Combine(appDir.FullName, "packages");
|
||||
Directory.CreateDirectory(packages);
|
||||
|
||||
var package = "Squirrel.Core.1.0.0.0-full.nupkg";
|
||||
File.Copy(IntegrationTestHelper.GetPath("fixtures", package), Path.Combine(packages, package));
|
||||
|
||||
var aGivenPackage = Path.Combine(packages, package);
|
||||
var baseEntry = ReleaseEntry.GenerateFromFile(aGivenPackage);
|
||||
|
||||
var updateInfo = UpdateInfo.Create(baseEntry, new[] { baseEntry }, "dontcare");
|
||||
|
||||
Assert.Empty(updateInfo.ReleasesToApply);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ThrowsWhenOnlyDeltaReleasesAreAvailable()
|
||||
{
|
||||
string tempDir;
|
||||
using (Utility.GetTempDirectory(out tempDir)) {
|
||||
var appDir = Directory.CreateDirectory(Path.Combine(tempDir, APP_ID));
|
||||
var packages = Path.Combine(appDir.FullName, "packages");
|
||||
Directory.CreateDirectory(packages);
|
||||
|
||||
var baseFile = "Squirrel.Core.1.0.0.0-full.nupkg";
|
||||
File.Copy(IntegrationTestHelper.GetPath("fixtures", baseFile),
|
||||
Path.Combine(packages, baseFile));
|
||||
var basePackage = Path.Combine(packages, baseFile);
|
||||
var baseEntry = ReleaseEntry.GenerateFromFile(basePackage);
|
||||
|
||||
var deltaFile = "Squirrel.Core.1.1.0.0-delta.nupkg";
|
||||
File.Copy(IntegrationTestHelper.GetPath("fixtures", deltaFile),
|
||||
Path.Combine(packages, deltaFile));
|
||||
var deltaPackage = Path.Combine(packages, deltaFile);
|
||||
var deltaEntry = ReleaseEntry.GenerateFromFile(deltaPackage);
|
||||
|
||||
Assert.Throws<Exception>(
|
||||
() => UpdateInfo.Create(baseEntry, new[] { deltaEntry }, "dontcare"));
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ApplyReleasesWithOneReleaseFile()
|
||||
{
|
||||
string tempDir;
|
||||
|
||||
using (Utility.GetTempDirectory(out tempDir)) {
|
||||
string appDir = Path.Combine(tempDir, APP_ID);
|
||||
string packagesDir = Path.Combine(appDir, "packages");
|
||||
Directory.CreateDirectory(packagesDir);
|
||||
|
||||
new[] {
|
||||
"Squirrel.Core.1.0.0.0-full.nupkg",
|
||||
"Squirrel.Core.1.1.0.0-full.nupkg",
|
||||
}.ForEach(x => File.Copy(IntegrationTestHelper.GetPath("fixtures", x), Path.Combine(packagesDir, x)));
|
||||
|
||||
using var fixture = UpdateManagerTestImpl.FromLocalPackageTempDir("", APP_ID, tempDir);
|
||||
|
||||
var baseEntry = ReleaseEntry.GenerateFromFile(Path.Combine(packagesDir, "Squirrel.Core.1.0.0.0-full.nupkg"));
|
||||
var latestFullEntry = ReleaseEntry.GenerateFromFile(Path.Combine(packagesDir, "Squirrel.Core.1.1.0.0-full.nupkg"));
|
||||
|
||||
var updateInfo = UpdateInfo.Create(baseEntry, new[] { latestFullEntry }, packagesDir);
|
||||
updateInfo.ReleasesToApply.Contains(latestFullEntry).ShouldBeTrue();
|
||||
|
||||
var progress = new List<int>();
|
||||
|
||||
await fixture.ApplyReleasesPublic(updateInfo, false, false, progress.Add);
|
||||
this.Log().Info("Progress: [{0}]", String.Join(",", progress));
|
||||
|
||||
progress
|
||||
.Aggregate(0, (acc, x) => {
|
||||
(x >= acc).ShouldBeTrue();
|
||||
return x;
|
||||
})
|
||||
.ShouldEqual(100);
|
||||
|
||||
var filesToFind = new[] {
|
||||
new { Name = "NLog.dll", Version = new Version("2.0.0.0") },
|
||||
new { Name = "NSync.Core.dll", Version = new Version("1.1.0.0") },
|
||||
};
|
||||
|
||||
filesToFind.ForEach(x => {
|
||||
var path = Path.Combine(tempDir, APP_ID, "staging", "app-1.1.0.0", x.Name);
|
||||
this.Log().Info("Looking for {0}", path);
|
||||
File.Exists(path).ShouldBeTrue();
|
||||
|
||||
var vi = FileVersionInfo.GetVersionInfo(path);
|
||||
var verInfo = new Version(vi.FileVersion ?? "1.0.0.0");
|
||||
x.Version.ShouldEqual(verInfo);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ApplyReleaseWhichRemovesAFile()
|
||||
{
|
||||
string tempDir;
|
||||
|
||||
using (Utility.GetTempDirectory(out tempDir)) {
|
||||
string appDir = Path.Combine(tempDir, APP_ID);
|
||||
string packagesDir = Path.Combine(appDir, "packages");
|
||||
Directory.CreateDirectory(packagesDir);
|
||||
|
||||
new[] {
|
||||
"Squirrel.Core.1.1.0.0-full.nupkg",
|
||||
"Squirrel.Core.1.2.0.0-full.nupkg",
|
||||
}.ForEach(x => File.Copy(IntegrationTestHelper.GetPath("fixtures", x), Path.Combine(packagesDir, x)));
|
||||
|
||||
using var fixture = UpdateManagerTestImpl.FromLocalPackageTempDir("", APP_ID, tempDir);
|
||||
|
||||
var baseEntry = ReleaseEntry.GenerateFromFile(Path.Combine(packagesDir, "Squirrel.Core.1.1.0.0-full.nupkg"));
|
||||
var latestFullEntry = ReleaseEntry.GenerateFromFile(Path.Combine(packagesDir, "Squirrel.Core.1.2.0.0-full.nupkg"));
|
||||
|
||||
var updateInfo = UpdateInfo.Create(baseEntry, new[] { latestFullEntry }, packagesDir);
|
||||
updateInfo.ReleasesToApply.Contains(latestFullEntry).ShouldBeTrue();
|
||||
|
||||
var progress = new List<int>();
|
||||
await fixture.ApplyReleasesPublic(updateInfo, false, false, progress.Add);
|
||||
this.Log().Info("Progress: [{0}]", String.Join(",", progress));
|
||||
|
||||
progress
|
||||
.Aggregate(0, (acc, x) => {
|
||||
(x >= acc).ShouldBeTrue();
|
||||
return x;
|
||||
})
|
||||
.ShouldEqual(100);
|
||||
|
||||
var rootDirectory = Path.Combine(tempDir, APP_ID, "staging", "app-1.2.0.0");
|
||||
|
||||
new[] {
|
||||
new { Name = "NLog.dll", Version = new Version("2.0.0.0") },
|
||||
new { Name = "NSync.Core.dll", Version = new Version("1.1.0.0") },
|
||||
}.ForEach(x => {
|
||||
var path = Path.Combine(rootDirectory, x.Name);
|
||||
this.Log().Info("Looking for {0}", path);
|
||||
File.Exists(path).ShouldBeTrue();
|
||||
});
|
||||
|
||||
var removedFile = Path.Combine("sub", "Ionic.Zip.dll");
|
||||
var deployedPath = Path.Combine(rootDirectory, removedFile);
|
||||
File.Exists(deployedPath).ShouldBeFalse();
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ApplyReleaseWhichMovesAFileToADifferentDirectory()
|
||||
{
|
||||
string tempDir;
|
||||
|
||||
using (Utility.GetTempDirectory(out tempDir)) {
|
||||
string appDir = Path.Combine(tempDir, APP_ID);
|
||||
string packagesDir = Path.Combine(appDir, "packages");
|
||||
Directory.CreateDirectory(packagesDir);
|
||||
|
||||
new[] {
|
||||
"Squirrel.Core.1.1.0.0-full.nupkg",
|
||||
"Squirrel.Core.1.3.0.0-full.nupkg",
|
||||
}.ForEach(x => File.Copy(IntegrationTestHelper.GetPath("fixtures", x), Path.Combine(packagesDir, x)));
|
||||
|
||||
using var fixture = UpdateManagerTestImpl.FromLocalPackageTempDir("", APP_ID, tempDir);
|
||||
|
||||
var baseEntry = ReleaseEntry.GenerateFromFile(Path.Combine(packagesDir, "Squirrel.Core.1.1.0.0-full.nupkg"));
|
||||
var latestFullEntry = ReleaseEntry.GenerateFromFile(Path.Combine(packagesDir, "Squirrel.Core.1.3.0.0-full.nupkg"));
|
||||
|
||||
var updateInfo = UpdateInfo.Create(baseEntry, new[] { latestFullEntry }, packagesDir);
|
||||
updateInfo.ReleasesToApply.Contains(latestFullEntry).ShouldBeTrue();
|
||||
|
||||
var progress = new List<int>();
|
||||
await fixture.ApplyReleasesPublic(updateInfo, false, false, progress.Add);
|
||||
this.Log().Info("Progress: [{0}]", String.Join(",", progress));
|
||||
|
||||
progress
|
||||
.Aggregate(0, (acc, x) => {
|
||||
(x >= acc).ShouldBeTrue();
|
||||
return x;
|
||||
})
|
||||
.ShouldEqual(100);
|
||||
|
||||
var rootDirectory = Path.Combine(tempDir, APP_ID, "staging", "app-1.3.0.0");
|
||||
|
||||
new[] {
|
||||
new { Name = "NLog.dll", Version = new Version("2.0.0.0") },
|
||||
new { Name = "NSync.Core.dll", Version = new Version("1.1.0.0") },
|
||||
}.ForEach(x => {
|
||||
var path = Path.Combine(rootDirectory, x.Name);
|
||||
this.Log().Info("Looking for {0}", path);
|
||||
File.Exists(path).ShouldBeTrue();
|
||||
});
|
||||
|
||||
var oldFile = Path.Combine(rootDirectory, "sub", "Ionic.Zip.dll");
|
||||
File.Exists(oldFile).ShouldBeFalse();
|
||||
|
||||
var newFile = Path.Combine(rootDirectory, "other", "Ionic.Zip.dll");
|
||||
File.Exists(newFile).ShouldBeTrue();
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ApplyReleasesWithDeltaReleases()
|
||||
{
|
||||
string tempDir;
|
||||
|
||||
using (Utility.GetTempDirectory(out tempDir)) {
|
||||
string appDir = Path.Combine(tempDir, APP_ID);
|
||||
string packagesDir = Path.Combine(appDir, "packages");
|
||||
Directory.CreateDirectory(packagesDir);
|
||||
|
||||
new[] {
|
||||
"Squirrel.Core.1.0.0.0-full.nupkg",
|
||||
"Squirrel.Core.1.1.0.0-delta.nupkg",
|
||||
"Squirrel.Core.1.1.0.0-full.nupkg",
|
||||
}.ForEach(x => File.Copy(IntegrationTestHelper.GetPath("fixtures", x), Path.Combine(packagesDir, x)));
|
||||
|
||||
using var fixture = UpdateManagerTestImpl.FromLocalPackageTempDir("", APP_ID, tempDir);
|
||||
|
||||
var baseEntry = ReleaseEntry.GenerateFromFile(Path.Combine(packagesDir, "Squirrel.Core.1.0.0.0-full.nupkg"));
|
||||
var deltaEntry = ReleaseEntry.GenerateFromFile(Path.Combine(packagesDir, "Squirrel.Core.1.1.0.0-delta.nupkg"));
|
||||
var latestFullEntry = ReleaseEntry.GenerateFromFile(Path.Combine(packagesDir, "Squirrel.Core.1.1.0.0-full.nupkg"));
|
||||
|
||||
var updateInfo = UpdateInfo.Create(baseEntry, new[] { deltaEntry, latestFullEntry }, packagesDir);
|
||||
updateInfo.ReleasesToApply.Contains(deltaEntry).ShouldBeTrue();
|
||||
|
||||
var progress = new List<int>();
|
||||
|
||||
await fixture.ApplyReleasesPublic(updateInfo, false, false, progress.Add);
|
||||
this.Log().Info("Progress: [{0}]", String.Join(",", progress));
|
||||
|
||||
// TODO: this is failing intermittently, not sure why but is not a big deal atm
|
||||
// progress
|
||||
// .Aggregate(0, (acc, x) => { (x >= acc).ShouldBeTrue(); return x; })
|
||||
// .ShouldEqual(100);
|
||||
|
||||
var filesToFind = new[] {
|
||||
new { Name = "NLog.dll", Version = new Version("2.0.0.0") },
|
||||
new { Name = "NSync.Core.dll", Version = new Version("1.1.0.0") },
|
||||
};
|
||||
|
||||
filesToFind.ForEach(x => {
|
||||
var path = Path.Combine(tempDir, APP_ID, "staging", "app-1.1.0.0", x.Name);
|
||||
this.Log().Info("Looking for {0}", path);
|
||||
File.Exists(path).ShouldBeTrue();
|
||||
|
||||
var vi = FileVersionInfo.GetVersionInfo(path);
|
||||
var verInfo = new Version(vi.FileVersion ?? "1.0.0.0");
|
||||
x.Version.ShouldEqual(verInfo);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task CreateFullPackagesFromDeltaSmokeTest()
|
||||
{
|
||||
string tempDir;
|
||||
using (Utility.GetTempDirectory(out tempDir)) {
|
||||
string appDir = Path.Combine(tempDir, APP_ID);
|
||||
string packagesDir = Path.Combine(appDir, "packages");
|
||||
Directory.CreateDirectory(packagesDir);
|
||||
|
||||
new[] {
|
||||
"Squirrel.Core.1.0.0.0-full.nupkg",
|
||||
"Squirrel.Core.1.1.0.0-delta.nupkg"
|
||||
}.ForEach(x => File.Copy(IntegrationTestHelper.GetPath("fixtures", x), Path.Combine(tempDir, APP_ID, "packages", x)));
|
||||
|
||||
using var fixture = UpdateManagerTestImpl.FromLocalPackageTempDir("", APP_ID, tempDir);
|
||||
|
||||
var baseEntry = ReleaseEntry.GenerateFromFile(Path.Combine(tempDir, APP_ID, "packages", "Squirrel.Core.1.0.0.0-full.nupkg"));
|
||||
var deltaEntry = ReleaseEntry.GenerateFromFile(Path.Combine(tempDir, APP_ID, "packages", "Squirrel.Core.1.1.0.0-delta.nupkg"));
|
||||
|
||||
var result = fixture.createFullPackagesFromDeltas(new[] { deltaEntry }, baseEntry, null);
|
||||
|
||||
var zp = new ZipPackage(Path.Combine(tempDir, APP_ID, "packages", result.Filename));
|
||||
zp.Version.ToString().ShouldEqual("1.1.0.0");
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task CreateShortcutsRoundTrip()
|
||||
{
|
||||
using var _1 = Utility.GetTempDirectory(out var tempDir);
|
||||
using var _2 = Utility.GetTempDirectory(out var remotePkgDir);
|
||||
|
||||
IntegrationTestHelper.CreateNewVersionInPackageDir("0.1.0", remotePkgDir);
|
||||
using var fixture = UpdateManagerTestImpl.FromLocalPackageTempDir(remotePkgDir, APP_ID, tempDir);
|
||||
await fixture.FullInstall();
|
||||
|
||||
fixture.CreateShortcutsForExecutable("SquirrelAwareApp.exe",
|
||||
ShortcutLocation.Desktop | ShortcutLocation.StartMenu | ShortcutLocation.Startup | ShortcutLocation.AppRoot, false, null, null);
|
||||
|
||||
Assert.True(File.Exists(Path.Combine(tempDir, APP_ID, "PublishSingleFileAwareApp.lnk")));
|
||||
|
||||
// NB: COM is Weird.
|
||||
Thread.Sleep(1000);
|
||||
fixture.RemoveShortcutsForExecutable("SquirrelAwareApp.exe",
|
||||
ShortcutLocation.Desktop | ShortcutLocation.StartMenu | ShortcutLocation.Startup | ShortcutLocation.AppRoot);
|
||||
|
||||
// NB: Squirrel-Aware first-run might still be running, slow
|
||||
// our roll before blowing away the temp path
|
||||
Thread.Sleep(1000);
|
||||
}
|
||||
|
||||
//[Fact]
|
||||
//public async Task GetShortcutsSmokeTest()
|
||||
//{
|
||||
// string remotePkgPath;
|
||||
// string path;
|
||||
|
||||
// using (Utility.WithTempDirectory(out path)) {
|
||||
// using (Utility.WithTempDirectory(out remotePkgPath))
|
||||
// using (var mgr = new UpdateManager(remotePkgPath, APP_ID, path)) {
|
||||
// IntegrationTestHelper.CreateFakeInstalledApp("1.0.0.1", remotePkgPath);
|
||||
// await mgr.FullInstall();
|
||||
// }
|
||||
|
||||
// var fixture = new ApplyReleasesImpl(Path.Combine(path, APP_ID));
|
||||
// var result = fixture.GetShortcutsForExecutable("SquirrelAwareApp.exe", ShortcutLocation.Desktop | ShortcutLocation.StartMenu | ShortcutLocation.Startup, null);
|
||||
|
||||
// Assert.Equal(3, result.Keys.Count);
|
||||
|
||||
// // NB: Squirrel-Aware first-run might still be running, slow
|
||||
// // our roll before blowing away the temp path
|
||||
// Thread.Sleep(1000);
|
||||
// }
|
||||
//}
|
||||
}
|
||||
}
|
||||
147
test/Squirrel.Tests/CheckForUpdateTests.cs
Normal file
147
test/Squirrel.Tests/CheckForUpdateTests.cs
Normal file
@@ -0,0 +1,147 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Squirrel.Tests.TestHelpers;
|
||||
using Xunit;
|
||||
|
||||
namespace Squirrel.Tests
|
||||
{
|
||||
public class CheckForUpdateTests
|
||||
{
|
||||
[Fact(Skip = "Rewrite this to be an integration test")]
|
||||
public void NewReleasesShouldBeDetected()
|
||||
{
|
||||
Assert.False(true, "Rewrite this to be an integration test");
|
||||
/*
|
||||
string localReleasesFile = Path.Combine(".", "theApp", "packages", "RELEASES");
|
||||
|
||||
var fileInfo = new Mock<FileInfoBase>();
|
||||
fileInfo.Setup(x => x.OpenRead())
|
||||
.Returns(File.OpenRead(IntegrationTestHelper.GetPath("fixtures", "RELEASES-OnePointOh")));
|
||||
|
||||
var fs = new Mock<IFileSystemFactory>();
|
||||
fs.Setup(x => x.GetFileInfo(localReleasesFile)).Returns(fileInfo.Object);
|
||||
|
||||
var urlDownloader = new Mock<IUrlDownloader>();
|
||||
var dlPath = IntegrationTestHelper.GetPath("fixtures", "RELEASES-OnePointOne");
|
||||
urlDownloader.Setup(x => x.DownloadUrl(It.IsAny<string>(), It.IsAny<IObserver<int>>()))
|
||||
.Returns(Observable.Return(File.ReadAllText(dlPath, Encoding.UTF8)));
|
||||
|
||||
var fixture = new UpdateManager("http://lol", "theApp", ".", fs.Object, urlDownloader.Object);
|
||||
var result = default(UpdateInfo);
|
||||
|
||||
using (fixture) {
|
||||
result = fixture.CheckForUpdate().First();
|
||||
}
|
||||
|
||||
Assert.NotNull(result);
|
||||
Assert.Equal(1, result.ReleasesToApply.Single().Version.Major);
|
||||
Assert.Equal(1, result.ReleasesToApply.Single().Version.Minor);
|
||||
*/
|
||||
}
|
||||
|
||||
[Fact(Skip = "Rewrite this to be an integration test")]
|
||||
public void CorruptedReleaseFileMeansWeStartFromScratch()
|
||||
{
|
||||
Assert.False(true, "Rewrite this to be an integration test");
|
||||
|
||||
/*
|
||||
string localPackagesDir = Path.Combine(".", "theApp", "packages");
|
||||
string localReleasesFile = Path.Combine(localPackagesDir, "RELEASES");
|
||||
|
||||
var fileInfo = new Mock<FileInfoBase>();
|
||||
fileInfo.Setup(x => x.Exists).Returns(true);
|
||||
fileInfo.Setup(x => x.OpenRead())
|
||||
.Returns(new MemoryStream(Encoding.UTF8.GetBytes("lol this isn't right")));
|
||||
|
||||
var dirInfo = new Mock<DirectoryInfoBase>();
|
||||
dirInfo.Setup(x => x.Exists).Returns(true);
|
||||
|
||||
var fs = new Mock<IFileSystemFactory>();
|
||||
fs.Setup(x => x.GetFileInfo(localReleasesFile)).Returns(fileInfo.Object);
|
||||
fs.Setup(x => x.CreateDirectoryRecursive(localPackagesDir)).Verifiable();
|
||||
fs.Setup(x => x.DeleteDirectoryRecursive(localPackagesDir)).Verifiable();
|
||||
fs.Setup(x => x.GetDirectoryInfo(localPackagesDir)).Returns(dirInfo.Object);
|
||||
|
||||
var urlDownloader = new Mock<IUrlDownloader>();
|
||||
var dlPath = IntegrationTestHelper.GetPath("fixtures", "RELEASES-OnePointOne");
|
||||
urlDownloader.Setup(x => x.DownloadUrl(It.IsAny<string>(), It.IsAny<IObserver<int>>()))
|
||||
.Returns(Observable.Return(File.ReadAllText(dlPath, Encoding.UTF8)));
|
||||
|
||||
var fixture = new UpdateManager("http://lol", "theApp", ".", fs.Object, urlDownloader.Object);
|
||||
using (fixture) {
|
||||
fixture.CheckForUpdate().First();
|
||||
}
|
||||
|
||||
fs.Verify(x => x.CreateDirectoryRecursive(localPackagesDir), Times.Once());
|
||||
fs.Verify(x => x.DeleteDirectoryRecursive(localPackagesDir), Times.Once());
|
||||
*/
|
||||
}
|
||||
|
||||
[Fact(Skip = "Rewrite this to be an integration test")]
|
||||
public void CorruptRemoteFileShouldThrowOnCheck()
|
||||
{
|
||||
Assert.False(true, "Rewrite this to be an integration test");
|
||||
|
||||
/*
|
||||
string localPackagesDir = Path.Combine(".", "theApp", "packages");
|
||||
string localReleasesFile = Path.Combine(localPackagesDir, "RELEASES");
|
||||
|
||||
var fileInfo = new Mock<FileInfoBase>();
|
||||
fileInfo.Setup(x => x.Exists).Returns(false);
|
||||
|
||||
var dirInfo = new Mock<DirectoryInfoBase>();
|
||||
dirInfo.Setup(x => x.Exists).Returns(true);
|
||||
|
||||
var fs = new Mock<IFileSystemFactory>();
|
||||
fs.Setup(x => x.GetFileInfo(localReleasesFile)).Returns(fileInfo.Object);
|
||||
fs.Setup(x => x.CreateDirectoryRecursive(localPackagesDir)).Verifiable();
|
||||
fs.Setup(x => x.DeleteDirectoryRecursive(localPackagesDir)).Verifiable();
|
||||
fs.Setup(x => x.GetDirectoryInfo(localPackagesDir)).Returns(dirInfo.Object);
|
||||
|
||||
var urlDownloader = new Mock<IUrlDownloader>();
|
||||
urlDownloader.Setup(x => x.DownloadUrl(It.IsAny<string>(), It.IsAny<IObserver<int>>()))
|
||||
.Returns(Observable.Return("lol this isn't right"));
|
||||
|
||||
var fixture = new UpdateManager("http://lol", "theApp", ".", fs.Object, urlDownloader.Object);
|
||||
|
||||
using (fixture) {
|
||||
Assert.Throws<Exception>(() => fixture.CheckForUpdate().First());
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
[Fact(Skip = "TODO")]
|
||||
public void IfLocalVersionGreaterThanRemoteWeRollback()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
[Fact(Skip = "TODO")]
|
||||
public void IfLocalAndRemoteAreEqualThenDoNothing()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(@"94689fede03fed7ab59c24337673a27837f0c3ec MyCoolApp-1.0.nupkg 1004502", "MyCoolApp", null)]
|
||||
[InlineData(@"0000000000000000000000000000000000000000 https://www.test.org/Folder/MyCoolApp-1.2-delta.nupkg?query=param 1231953", "MyCoolApp", "https://www.test.org/Folder")]
|
||||
public async Task WebSourceRequestsExpectedUrls(string releaseEntry, string releaseName, string baseUrl)
|
||||
{
|
||||
baseUrl = baseUrl ?? "https://example.com/files";
|
||||
var dl = new FakeDownloader();
|
||||
var source = new Sources.SimpleWebSource("https://example.com/files", dl);
|
||||
|
||||
dl.MockedResponseBytes = Encoding.UTF8.GetBytes(releaseEntry);
|
||||
var releases = await source.GetReleaseFeed(null, null);
|
||||
Assert.True(releases.Count() == 1);
|
||||
Assert.Equal(releaseName, releases[0].PackageName);
|
||||
Assert.Equal("https://example.com/files/RELEASES", new Uri(dl.LastUrl).GetLeftPart(UriPartial.Path));
|
||||
|
||||
await source.DownloadReleaseEntry(releases[0], "test", null);
|
||||
Assert.Equal(baseUrl + "/" + releases[0].Filename, new Uri(dl.LastUrl).GetLeftPart(UriPartial.Path));
|
||||
}
|
||||
}
|
||||
}
|
||||
52
test/Squirrel.Tests/ContentTypeTests.cs
Normal file
52
test/Squirrel.Tests/ContentTypeTests.cs
Normal file
@@ -0,0 +1,52 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Xml;
|
||||
using Squirrel;
|
||||
using Squirrel.NuGet;
|
||||
using Squirrel.Tests.TestHelpers;
|
||||
using Xunit;
|
||||
|
||||
namespace Squirrel.Tests
|
||||
{
|
||||
public class ContentTypeTests
|
||||
{
|
||||
[Theory]
|
||||
[InlineData("basic.xml", "basic-merged.xml")]
|
||||
[InlineData("complex.xml", "complex-merged.xml")]
|
||||
public void MergeContentTypes(string inputFileName, string expectedFileName)
|
||||
{
|
||||
var inputFile = IntegrationTestHelper.GetPath("fixtures", "content-types", inputFileName);
|
||||
var expectedFile = IntegrationTestHelper.GetPath("fixtures", "content-types", expectedFileName);
|
||||
var tempFile = Path.GetTempFileName() + ".xml";
|
||||
|
||||
var expected = new XmlDocument();
|
||||
expected.Load(expectedFile);
|
||||
|
||||
var existingTypes = GetContentTypes(expected);
|
||||
|
||||
try {
|
||||
File.Copy(inputFile, tempFile);
|
||||
|
||||
var actual = new XmlDocument();
|
||||
actual.Load(tempFile);
|
||||
|
||||
ContentType.Merge(actual);
|
||||
|
||||
var actualTypes = GetContentTypes(actual);
|
||||
|
||||
Assert.Equal(existingTypes, actualTypes);
|
||||
} finally {
|
||||
File.Delete(tempFile);
|
||||
}
|
||||
}
|
||||
|
||||
static IEnumerable<XmlElement> GetContentTypes(XmlNode doc)
|
||||
{
|
||||
var expectedTypesElement = doc.FirstChild.NextSibling;
|
||||
return expectedTypesElement.ChildNodes.OfType<XmlElement>();
|
||||
}
|
||||
}
|
||||
}
|
||||
347
test/Squirrel.Tests/DeltaPackageTests.cs
Normal file
347
test/Squirrel.Tests/DeltaPackageTests.cs
Normal file
@@ -0,0 +1,347 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Squirrel.NuGet;
|
||||
using Squirrel;
|
||||
using Squirrel.SimpleSplat;
|
||||
using Squirrel.Tests.TestHelpers;
|
||||
using Xunit;
|
||||
using Xunit.Abstractions;
|
||||
using NuGet.Versioning;
|
||||
using Squirrel.CommandLine;
|
||||
|
||||
namespace Squirrel.Tests
|
||||
{
|
||||
public class ApplyDeltaPackageTests : TestLoggingBase
|
||||
{
|
||||
public ApplyDeltaPackageTests(ITestOutputHelper log) : base(log)
|
||||
{
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ApplyDeltaPackageSmokeTest()
|
||||
{
|
||||
var basePackage = IntegrationTestHelper.GetPath("fixtures", "Squirrel.Core.1.0.0.0-full.nupkg");
|
||||
var deltaPackage = IntegrationTestHelper.GetPath("fixtures", "Squirrel.Core.1.1.0.0-delta.nupkg");
|
||||
var expectedPackageFile = IntegrationTestHelper.GetPath("fixtures", "Squirrel.Core.1.1.0.0-full.nupkg");
|
||||
var outFile = Path.GetTempFileName() + ".nupkg";
|
||||
|
||||
try {
|
||||
var deltaBuilder = new DeltaPackage();
|
||||
deltaBuilder.ApplyDeltaPackage(basePackage, deltaPackage, outFile);
|
||||
|
||||
var result = new ZipPackage(outFile);
|
||||
var expected = new ZipPackage(expectedPackageFile);
|
||||
|
||||
result.Id.ShouldEqual(expected.Id);
|
||||
result.Version.ShouldEqual(expected.Version);
|
||||
|
||||
this.Log().Info("Expected file list:");
|
||||
var expectedList = expected.Files.Select(x => x.Path).OrderBy(x => x).ToList();
|
||||
expectedList.ForEach(x => this.Log().Info(x));
|
||||
|
||||
this.Log().Info("Actual file list:");
|
||||
var actualList = result.Files.Select(x => x.Path).OrderBy(x => x).ToList();
|
||||
actualList.ForEach(x => this.Log().Info(x));
|
||||
|
||||
Enumerable.Zip(expectedList, actualList, (e, a) => e == a)
|
||||
.All(x => x != false)
|
||||
.ShouldBeTrue();
|
||||
} finally {
|
||||
if (File.Exists(outFile)) {
|
||||
File.Delete(outFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ApplyDeltaWithBothBsdiffAndNormalDiffDoesntFail()
|
||||
{
|
||||
var basePackage = IntegrationTestHelper.GetPath("fixtures", "slack-1.1.8-full.nupkg");
|
||||
var deltaPackage = IntegrationTestHelper.GetPath("fixtures", "slack-1.2.0-delta.nupkg");
|
||||
var outFile = Path.GetTempFileName() + ".nupkg";
|
||||
|
||||
try {
|
||||
var deltaBuilder = new DeltaPackage();
|
||||
deltaBuilder.ApplyDeltaPackage(basePackage, deltaPackage, outFile);
|
||||
|
||||
var result = new ZipPackage(outFile);
|
||||
|
||||
result.Id.ShouldEqual("slack");
|
||||
result.Version.ShouldEqual(SemanticVersion.Parse("1.2.0"));
|
||||
} finally {
|
||||
if (File.Exists(outFile)) {
|
||||
File.Delete(outFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ApplyMultipleDeltasFast()
|
||||
{
|
||||
var basePackage = IntegrationTestHelper.GetPath("fixtures", "Clowd-3.4.287-full.nupkg");
|
||||
var deltaPackage1 = IntegrationTestHelper.GetPath("fixtures", "Clowd-3.4.288-delta.nupkg");
|
||||
var deltaPackage2 = IntegrationTestHelper.GetPath("fixtures", "Clowd-3.4.291-delta.nupkg");
|
||||
var deltaPackage3 = IntegrationTestHelper.GetPath("fixtures", "Clowd-3.4.292-delta.nupkg");
|
||||
|
||||
using var t1 = Utility.GetTempDirectory(out var appDir);
|
||||
using var t2 = Utility.GetTempDirectory(out var updateDir);
|
||||
|
||||
using var um = UpdateManagerTestImpl.FromLocalPackageTempDir(updateDir, "theApp", appDir);
|
||||
var pkgDir = um.Config.PackagesDir;
|
||||
|
||||
File.Copy(basePackage, Path.Combine(pkgDir, Path.GetFileName(basePackage)));
|
||||
File.Copy(deltaPackage1, Path.Combine(pkgDir, Path.GetFileName(deltaPackage1)));
|
||||
File.Copy(deltaPackage2, Path.Combine(pkgDir, Path.GetFileName(deltaPackage2)));
|
||||
File.Copy(deltaPackage3, Path.Combine(pkgDir, Path.GetFileName(deltaPackage3)));
|
||||
|
||||
var baseEntry = ReleaseEntry.GenerateFromFile(basePackage);
|
||||
|
||||
var toApply = new [] {
|
||||
ReleaseEntry.GenerateFromFile(deltaPackage1),
|
||||
ReleaseEntry.GenerateFromFile(deltaPackage2),
|
||||
ReleaseEntry.GenerateFromFile(deltaPackage3),
|
||||
};
|
||||
|
||||
List<int> progress = new List<int>();
|
||||
|
||||
var newEntry = um.createFullPackagesFromDeltas(toApply, baseEntry, progress.Add);
|
||||
|
||||
var outFile = Path.Combine(pkgDir, newEntry.Filename);
|
||||
var result = new ZipPackage(outFile);
|
||||
result.Id.ShouldEqual("Clowd");
|
||||
result.Version.ShouldEqual(SemanticVersion.Parse("3.4.292"));
|
||||
}
|
||||
|
||||
[Fact(Skip = "Rewrite this test, the original uses too many heavyweight fixtures")]
|
||||
public void ApplyMultipleDeltaPackagesGeneratesCorrectHash()
|
||||
{
|
||||
Assert.True(false, "Rewrite this test, the original uses too many heavyweight fixtures");
|
||||
}
|
||||
}
|
||||
|
||||
public class CreateDeltaPackageTests : IEnableLogger
|
||||
{
|
||||
[Fact]
|
||||
public void CreateDeltaPackageIntegrationTest()
|
||||
{
|
||||
var basePackage = IntegrationTestHelper.GetPath("fixtures", "Squirrel.Tests.0.1.0-pre.nupkg");
|
||||
var newPackage = IntegrationTestHelper.GetPath("fixtures", "Squirrel.Tests.0.2.0-pre.nupkg");
|
||||
|
||||
var baseFixture = new ReleasePackageBuilder(basePackage);
|
||||
var fixture = new ReleasePackageBuilder(newPackage);
|
||||
|
||||
var tempFiles = Enumerable.Range(0, 3)
|
||||
.Select(_ => Path.GetTempPath() + Guid.NewGuid().ToString() + ".nupkg")
|
||||
.ToArray();
|
||||
|
||||
try {
|
||||
baseFixture.CreateReleasePackage(tempFiles[0]);
|
||||
fixture.CreateReleasePackage(tempFiles[1]);
|
||||
|
||||
(new FileInfo(baseFixture.ReleasePackageFile)).Exists.ShouldBeTrue();
|
||||
(new FileInfo(fixture.ReleasePackageFile)).Exists.ShouldBeTrue();
|
||||
|
||||
var deltaBuilder = new DeltaPackageBuilder();
|
||||
deltaBuilder.CreateDeltaPackage(baseFixture, fixture, tempFiles[2]);
|
||||
|
||||
var fullPkg = new ZipPackage(tempFiles[1]);
|
||||
var deltaPkg = new ZipPackage(tempFiles[2]);
|
||||
|
||||
//
|
||||
// Package Checks
|
||||
//
|
||||
|
||||
fullPkg.Id.ShouldEqual(deltaPkg.Id);
|
||||
fullPkg.Version.CompareTo(deltaPkg.Version).ShouldEqual(0);
|
||||
|
||||
// Delta packages should be smaller than the original!
|
||||
var fileInfos = tempFiles.Select(x => new FileInfo(x)).ToArray();
|
||||
this.Log().Info("Base Size: {0}, Current Size: {1}, Delta Size: {2}",
|
||||
fileInfos[0].Length, fileInfos[1].Length, fileInfos[2].Length);
|
||||
|
||||
(fileInfos[2].Length - fileInfos[1].Length).ShouldBeLessThan(0);
|
||||
|
||||
//
|
||||
// File Checks
|
||||
///
|
||||
|
||||
var deltaPkgFiles = deltaPkg.Files.ToList();
|
||||
deltaPkgFiles.Count.ShouldBeGreaterThan(0);
|
||||
|
||||
this.Log().Info("Files in delta package:");
|
||||
deltaPkgFiles.ForEach(x => this.Log().Info(x.Path));
|
||||
|
||||
var newFilesAdded = new[] {
|
||||
"Newtonsoft.Json.dll",
|
||||
//"Refit.dll",
|
||||
//"Refit-Portable.dll",
|
||||
//"Castle.Core.dll",
|
||||
}.Select(x => x.ToLowerInvariant());
|
||||
|
||||
// vNext adds a dependency on Refit
|
||||
newFilesAdded
|
||||
.All(x => deltaPkgFiles.Any(y => y.Path.ToLowerInvariant().Contains(x)))
|
||||
.ShouldBeTrue();
|
||||
|
||||
// All the other files should be diffs and shasums
|
||||
deltaPkgFiles
|
||||
.Where(x => !newFilesAdded.Any(y => x.Path.ToLowerInvariant().Contains(y)))
|
||||
.All(x => x.Path.ToLowerInvariant().EndsWith("bsdiff") || x.Path.ToLowerInvariant().EndsWith("shasum"))
|
||||
.ShouldBeTrue();
|
||||
|
||||
// Every .diff file should have a shasum file
|
||||
deltaPkg.Files.Any(x => x.Path.ToLowerInvariant().EndsWith(".bsdiff")).ShouldBeTrue();
|
||||
deltaPkg.Files
|
||||
.Where(x => x.Path.ToLowerInvariant().EndsWith(".bsdiff"))
|
||||
.ForEach(x => {
|
||||
var lookingFor = x.Path.Replace(".bsdiff", ".shasum");
|
||||
this.Log().Info("Looking for corresponding shasum file: {0}", lookingFor);
|
||||
deltaPkg.Files.Any(y => y.Path == lookingFor).ShouldBeTrue();
|
||||
});
|
||||
} finally {
|
||||
tempFiles.ForEach(File.Delete);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WhenBasePackageIsNewerThanNewPackageThrowException()
|
||||
{
|
||||
var basePackage = IntegrationTestHelper.GetPath("fixtures", "Squirrel.Tests.0.2.0-pre.nupkg");
|
||||
var newPackage = IntegrationTestHelper.GetPath("fixtures", "Squirrel.Tests.0.1.0-pre.nupkg");
|
||||
|
||||
var baseFixture = new ReleasePackageBuilder(basePackage);
|
||||
var fixture = new ReleasePackageBuilder(newPackage);
|
||||
|
||||
var tempFiles = Enumerable.Range(0, 3)
|
||||
.Select(_ => Path.GetTempPath() + Guid.NewGuid().ToString() + ".nupkg")
|
||||
.ToArray();
|
||||
|
||||
try {
|
||||
baseFixture.CreateReleasePackage(tempFiles[0]);
|
||||
fixture.CreateReleasePackage(tempFiles[1]);
|
||||
|
||||
(new FileInfo(baseFixture.ReleasePackageFile)).Exists.ShouldBeTrue();
|
||||
(new FileInfo(fixture.ReleasePackageFile)).Exists.ShouldBeTrue();
|
||||
|
||||
Assert.Throws<InvalidOperationException>(() => {
|
||||
var deltaBuilder = new DeltaPackageBuilder();
|
||||
deltaBuilder.CreateDeltaPackage(baseFixture, fixture, tempFiles[2]);
|
||||
});
|
||||
} finally {
|
||||
tempFiles.ForEach(File.Delete);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WhenBasePackageReleaseIsNullThrowsException()
|
||||
{
|
||||
var basePackage = IntegrationTestHelper.GetPath("fixtures", "Squirrel.Core.1.0.0.0.nupkg");
|
||||
var newPackage = IntegrationTestHelper.GetPath("fixtures", "Squirrel.Core.1.1.0.0.nupkg");
|
||||
|
||||
var sourceDir = IntegrationTestHelper.GetPath("fixtures", "packages");
|
||||
(new DirectoryInfo(sourceDir)).Exists.ShouldBeTrue();
|
||||
|
||||
var baseFixture = new ReleasePackageBuilder(basePackage);
|
||||
var fixture = new ReleasePackageBuilder(newPackage);
|
||||
|
||||
var tempFile = Path.GetTempPath() + Guid.NewGuid() + ".nupkg";
|
||||
|
||||
try {
|
||||
Assert.Throws<ArgumentException>(() => {
|
||||
var deltaBuilder = new DeltaPackageBuilder();
|
||||
deltaBuilder.CreateDeltaPackage(baseFixture, fixture, tempFile);
|
||||
});
|
||||
} finally {
|
||||
File.Delete(tempFile);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WhenBasePackageDoesNotExistThrowException()
|
||||
{
|
||||
var basePackage = IntegrationTestHelper.GetPath("fixtures", "Squirrel.Tests.0.1.0-pre.nupkg");
|
||||
var newPackage = IntegrationTestHelper.GetPath("fixtures", "Squirrel.Tests.0.2.0-pre.nupkg");
|
||||
|
||||
var baseFixture = new ReleasePackageBuilder(basePackage);
|
||||
var fixture = new ReleasePackageBuilder(newPackage);
|
||||
|
||||
var tempFiles = Enumerable.Range(0, 3)
|
||||
.Select(_ => Path.GetTempPath() + Guid.NewGuid().ToString() + ".nupkg")
|
||||
.ToArray();
|
||||
|
||||
try {
|
||||
baseFixture.CreateReleasePackage(tempFiles[0]);
|
||||
fixture.CreateReleasePackage(tempFiles[1]);
|
||||
|
||||
(new FileInfo(baseFixture.ReleasePackageFile)).Exists.ShouldBeTrue();
|
||||
(new FileInfo(fixture.ReleasePackageFile)).Exists.ShouldBeTrue();
|
||||
|
||||
// NOW WATCH AS THE FILE DISAPPEARS
|
||||
File.Delete(baseFixture.ReleasePackageFile);
|
||||
|
||||
Assert.Throws<FileNotFoundException>(() => {
|
||||
var deltaBuilder = new DeltaPackageBuilder();
|
||||
deltaBuilder.CreateDeltaPackage(baseFixture, fixture, tempFiles[2]);
|
||||
});
|
||||
} finally {
|
||||
tempFiles.ForEach(File.Delete);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WhenNewPackageDoesNotExistThrowException()
|
||||
{
|
||||
var basePackage = IntegrationTestHelper.GetPath("fixtures", "Squirrel.Tests.0.1.0-pre.nupkg");
|
||||
var newPackage = IntegrationTestHelper.GetPath("fixtures", "Squirrel.Tests.0.2.0-pre.nupkg");
|
||||
|
||||
var baseFixture = new ReleasePackageBuilder(basePackage);
|
||||
var fixture = new ReleasePackageBuilder(newPackage);
|
||||
|
||||
var tempFiles = Enumerable.Range(0, 3)
|
||||
.Select(_ => Path.GetTempPath() + Guid.NewGuid().ToString() + ".nupkg")
|
||||
.ToArray();
|
||||
|
||||
try {
|
||||
baseFixture.CreateReleasePackage(tempFiles[0]);
|
||||
fixture.CreateReleasePackage(tempFiles[1]);
|
||||
|
||||
(new FileInfo(baseFixture.ReleasePackageFile)).Exists.ShouldBeTrue();
|
||||
(new FileInfo(fixture.ReleasePackageFile)).Exists.ShouldBeTrue();
|
||||
|
||||
// NOW WATCH AS THE FILE DISAPPEARS
|
||||
File.Delete(fixture.ReleasePackageFile);
|
||||
|
||||
Assert.Throws<FileNotFoundException>(() => {
|
||||
var deltaBuilder = new DeltaPackageBuilder();
|
||||
deltaBuilder.CreateDeltaPackage(baseFixture, fixture, tempFiles[2]);
|
||||
});
|
||||
} finally {
|
||||
tempFiles.ForEach(File.Delete);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void HandleBsDiffWithoutExtraData()
|
||||
{
|
||||
var baseFileData = new byte[] { 1, 1, 1, 1 };
|
||||
var newFileData = new byte[] { 2, 1, 1, 1 };
|
||||
|
||||
byte[] patchData;
|
||||
|
||||
using (var patchOut = new MemoryStream()) {
|
||||
Bsdiff.BinaryPatchUtility.Create(baseFileData, newFileData, patchOut);
|
||||
patchData = patchOut.ToArray();
|
||||
}
|
||||
|
||||
using (var toPatch = new MemoryStream(baseFileData))
|
||||
using (var patched = new MemoryStream()) {
|
||||
Bsdiff.BinaryPatchUtility.Apply(toPatch, () => new MemoryStream(patchData), patched);
|
||||
|
||||
Assert.Equal(newFileData, patched.ToArray());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
194
test/Squirrel.Tests/DownloadReleasesTests.cs
Normal file
194
test/Squirrel.Tests/DownloadReleasesTests.cs
Normal file
@@ -0,0 +1,194 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Squirrel.SimpleSplat;
|
||||
using Squirrel.Tests.TestHelpers;
|
||||
using Xunit;
|
||||
|
||||
namespace Squirrel.Tests
|
||||
{
|
||||
public class DownloadReleasesTests
|
||||
{
|
||||
[Fact(Skip = "Rewrite this to be an integration test")]
|
||||
public void ChecksumShouldFailIfFilesAreMissing()
|
||||
{
|
||||
Assert.False(true, "Rewrite this to be an integration test");
|
||||
|
||||
/*
|
||||
var filename = "Squirrel.Core.1.0.0.0.nupkg";
|
||||
var nuGetPkg = IntegrationTestHelper.GetPath("fixtures", filename);
|
||||
var fs = new Mock<IFileSystemFactory>();
|
||||
var urlDownloader = new Mock<IUrlDownloader>();
|
||||
|
||||
ReleaseEntry entry;
|
||||
using (var f = File.OpenRead(nuGetPkg)) {
|
||||
entry = ReleaseEntry.GenerateFromFile(f, filename);
|
||||
}
|
||||
|
||||
var fileInfo = new Mock<FileInfoBase>();
|
||||
fileInfo.Setup(x => x.OpenRead()).Returns(File.OpenRead(nuGetPkg));
|
||||
fileInfo.Setup(x => x.Exists).Returns(false);
|
||||
|
||||
fs.Setup(x => x.GetFileInfo(Path.Combine(".", "theApp", "packages", filename))).Returns(fileInfo.Object);
|
||||
|
||||
var fixture = ExposedObject.From(
|
||||
new UpdateManager("http://lol", "theApp", ".", fs.Object, urlDownloader.Object));
|
||||
|
||||
bool shouldDie = true;
|
||||
try {
|
||||
// NB: We can't use Assert.Throws here because the binder
|
||||
// will try to pick the wrong method
|
||||
fixture.checksumPackage(entry);
|
||||
} catch (Exception) {
|
||||
shouldDie = false;
|
||||
}
|
||||
|
||||
shouldDie.ShouldBeFalse();
|
||||
*/
|
||||
}
|
||||
|
||||
[Fact(Skip = "Rewrite this to be an integration test")]
|
||||
public void ChecksumShouldFailIfFilesAreBogus()
|
||||
{
|
||||
Assert.False(true, "Rewrite this to be an integration test");
|
||||
|
||||
/*
|
||||
var filename = "Squirrel.Core.1.0.0.0.nupkg";
|
||||
var nuGetPkg = IntegrationTestHelper.GetPath("fixtures", filename);
|
||||
var fs = new Mock<IFileSystemFactory>();
|
||||
var urlDownloader = new Mock<IUrlDownloader>();
|
||||
|
||||
ReleaseEntry entry;
|
||||
using (var f = File.OpenRead(nuGetPkg)) {
|
||||
entry = ReleaseEntry.GenerateFromFile(f, filename);
|
||||
}
|
||||
|
||||
var fileInfo = new Mock<FileInfoBase>();
|
||||
fileInfo.Setup(x => x.OpenRead()).Returns(new MemoryStream(Encoding.UTF8.GetBytes("Lol broken")));
|
||||
fileInfo.Setup(x => x.Exists).Returns(true);
|
||||
fileInfo.Setup(x => x.Length).Returns(new FileInfo(nuGetPkg).Length);
|
||||
fileInfo.Setup(x => x.Delete()).Verifiable();
|
||||
|
||||
fs.Setup(x => x.GetFileInfo(Path.Combine(".", "theApp", "packages", filename))).Returns(fileInfo.Object);
|
||||
|
||||
var fixture = ExposedObject.From(
|
||||
new UpdateManager("http://lol", "theApp", ".", fs.Object, urlDownloader.Object));
|
||||
|
||||
bool shouldDie = true;
|
||||
try {
|
||||
fixture.checksumPackage(entry);
|
||||
} catch (Exception ex) {
|
||||
this.Log().InfoException("Checksum failure", ex);
|
||||
shouldDie = false;
|
||||
}
|
||||
|
||||
shouldDie.ShouldBeFalse();
|
||||
fileInfo.Verify(x => x.Delete(), Times.Once());
|
||||
*/
|
||||
}
|
||||
|
||||
[Fact(Skip = "Rewrite this to be an integration test")]
|
||||
public async Task DownloadReleasesFromHttpServerIntegrationTest()
|
||||
{
|
||||
Assert.False(true, "Rewrite this to not use the SampleUpdatingApp");
|
||||
|
||||
/*
|
||||
string tempDir = null;
|
||||
|
||||
var updateDir = new DirectoryInfo(IntegrationTestHelper.GetPath("..", "SampleUpdatingApp", "SampleReleasesFolder"));
|
||||
|
||||
IDisposable disp;
|
||||
try {
|
||||
var httpServer = new StaticHttpServer(30405, updateDir.FullName);
|
||||
disp = httpServer.Start();
|
||||
} catch (HttpListenerException) {
|
||||
Assert.False(true, @"Windows sucks, go run 'netsh http add urlacl url=http://+:30405/ user=MYMACHINE\MyUser");
|
||||
return;
|
||||
}
|
||||
|
||||
var entriesToDownload = updateDir.GetFiles("*.nupkg")
|
||||
.Select(x => ReleaseEntry.GenerateFromFile(x.FullName))
|
||||
.ToArray();
|
||||
|
||||
entriesToDownload.Count().ShouldBeGreaterThan(0);
|
||||
|
||||
using (disp)
|
||||
using (Utility.WithTempDirectory(out tempDir)) {
|
||||
// NB: This is normally done by CheckForUpdates, but since
|
||||
// we're skipping that in the test we have to do it ourselves
|
||||
Directory.CreateDirectory(Path.Combine(tempDir, "SampleUpdatingApp", "packages"));
|
||||
|
||||
var fixture = new UpdateManager("http://localhost:30405", "SampleUpdatingApp", tempDir);
|
||||
using (fixture) {
|
||||
var progress = new List<int>();
|
||||
await fixture.DownloadReleases(entriesToDownload, progress.Add);
|
||||
|
||||
progress
|
||||
.Aggregate(0, (acc, x) => { x.ShouldBeGreaterThan(acc); return x; })
|
||||
.ShouldEqual(100);
|
||||
}
|
||||
|
||||
entriesToDownload.ForEach(x => {
|
||||
this.Log().Info("Looking for {0}", x.Filename);
|
||||
var actualFile = Path.Combine(tempDir, "SampleUpdatingApp", "packages", x.Filename);
|
||||
File.Exists(actualFile).ShouldBeTrue();
|
||||
|
||||
var actualEntry = ReleaseEntry.GenerateFromFile(actualFile);
|
||||
actualEntry.SHA1.ShouldEqual(x.SHA1);
|
||||
actualEntry.Version.ShouldEqual(x.Version);
|
||||
});
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
[Fact(Skip = "Rewrite this to be an integration test")]
|
||||
public async Task DownloadReleasesFromFileDirectoryIntegrationTest()
|
||||
{
|
||||
Assert.False(true, "Rewrite this to not use the SampleUpdatingApp");
|
||||
|
||||
/*
|
||||
string tempDir = null;
|
||||
|
||||
var updateDir = new DirectoryInfo(IntegrationTestHelper.GetPath("..", "SampleUpdatingApp", "SampleReleasesFolder"));
|
||||
|
||||
var entriesToDownload = updateDir.GetFiles("*.nupkg")
|
||||
.Select(x => ReleaseEntry.GenerateFromFile(x.FullName))
|
||||
.ToArray();
|
||||
|
||||
entriesToDownload.Count().ShouldBeGreaterThan(0);
|
||||
|
||||
using (Utility.WithTempDirectory(out tempDir)) {
|
||||
// NB: This is normally done by CheckForUpdates, but since
|
||||
// we're skipping that in the test we have to do it ourselves
|
||||
Directory.CreateDirectory(Path.Combine(tempDir, "SampleUpdatingApp", "packages"));
|
||||
|
||||
var fixture = new UpdateManager(updateDir.FullName, "SampleUpdatingApp", tempDir);
|
||||
using (fixture) {
|
||||
var progress = new List<int>();
|
||||
|
||||
await fixture.DownloadReleases(entriesToDownload, progress.Add);
|
||||
this.Log().Info("Progress: [{0}]", String.Join(",", progress));
|
||||
|
||||
progress
|
||||
.Aggregate(0, (acc, x) => { x.ShouldBeGreaterThan(acc); return x; })
|
||||
.ShouldEqual(100);
|
||||
}
|
||||
|
||||
entriesToDownload.ForEach(x => {
|
||||
this.Log().Info("Looking for {0}", x.Filename);
|
||||
var actualFile = Path.Combine(tempDir, "SampleUpdatingApp", "packages", x.Filename);
|
||||
File.Exists(actualFile).ShouldBeTrue();
|
||||
|
||||
var actualEntry = ReleaseEntry.GenerateFromFile(actualFile);
|
||||
actualEntry.SHA1.ShouldEqual(x.SHA1);
|
||||
actualEntry.Version.ShouldEqual(x.Version);
|
||||
});
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
29
test/Squirrel.Tests/Init.cs
Normal file
29
test/Squirrel.Tests/Init.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using Squirrel.CommandLine;
|
||||
using Xunit.Abstractions;
|
||||
using Xunit.Sdk;
|
||||
|
||||
[assembly: Xunit.TestFramework("Squirrel.Tests.TestsInit", "Squirrel.Tests")]
|
||||
|
||||
namespace Squirrel.Tests
|
||||
{
|
||||
public class TestsInit : XunitTestFramework
|
||||
{
|
||||
public TestsInit(IMessageSink messageSink)
|
||||
: base(messageSink)
|
||||
{
|
||||
// Place initialization code here
|
||||
var baseDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location.Replace("file:///", ""));
|
||||
HelperFile.AddSearchPath(Path.Combine(baseDir, "..", "..", "..", "..", "vendor"));
|
||||
HelperFile.AddSearchPath(Path.Combine(baseDir, "..", "..", "..", "..", "vendor", "7zip"));
|
||||
HelperFile.AddSearchPath(Path.Combine(baseDir, "..", "..", "..", "..", "vendor", "wix"));
|
||||
}
|
||||
|
||||
public new void Dispose()
|
||||
{
|
||||
// Place tear down code here
|
||||
base.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
7
test/Squirrel.Tests/Properties/AssemblyInfo.cs
Normal file
7
test/Squirrel.Tests/Properties/AssemblyInfo.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using Xunit;
|
||||
|
||||
[assembly: ComVisible(false)]
|
||||
[assembly: CollectionBehavior(MaxParallelThreads=1, DisableTestParallelization=true)]
|
||||
[assembly: AssemblyMetadata("SquirrelAwareVersion", "1")]
|
||||
414
test/Squirrel.Tests/ReleaseEntryTests.cs
Normal file
414
test/Squirrel.Tests/ReleaseEntryTests.cs
Normal file
@@ -0,0 +1,414 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Squirrel;
|
||||
using Squirrel.Tests.TestHelpers;
|
||||
using Xunit;
|
||||
using Squirrel.NuGet;
|
||||
using NuGet.Versioning;
|
||||
using Squirrel.CommandLine;
|
||||
|
||||
namespace Squirrel.Tests
|
||||
{
|
||||
public class ReleaseEntryTests
|
||||
{
|
||||
[Theory]
|
||||
[InlineData(@"94689fede03fed7ab59c24337673a27837f0c3ec MyCoolApp-1.0.nupkg 1004502", "MyCoolApp-1.0.nupkg", 1004502, null, null)]
|
||||
[InlineData(@"3a2eadd15dd984e4559f2b4d790ec8badaeb6a39 MyCoolApp-1.1.nupkg 1040561", "MyCoolApp-1.1.nupkg", 1040561, null, null)]
|
||||
[InlineData(@"14db31d2647c6d2284882a2e101924a9c409ee67 MyCoolApp-1.1.nupkg.delta 80396", "MyCoolApp-1.1.nupkg.delta", 80396, null, null)]
|
||||
[InlineData(@"0000000000000000000000000000000000000000 http://test.org/Folder/MyCoolApp-1.2.nupkg 2569", "MyCoolApp-1.2.nupkg", 2569, "http://test.org/Folder/", null)]
|
||||
[InlineData(@"0000000000000000000000000000000000000000 http://test.org/Folder/MyCoolApp-1.2.nupkg?query=param 2569", "MyCoolApp-1.2.nupkg", 2569, "http://test.org/Folder/", "?query=param")]
|
||||
[InlineData(@"0000000000000000000000000000000000000000 https://www.test.org/Folder/MyCoolApp-1.2-delta.nupkg 1231953", "MyCoolApp-1.2-delta.nupkg", 1231953, "https://www.test.org/Folder/", null)]
|
||||
[InlineData(@"0000000000000000000000000000000000000000 https://www.test.org/Folder/MyCoolApp-1.2-delta.nupkg?query=param 1231953", "MyCoolApp-1.2-delta.nupkg", 1231953, "https://www.test.org/Folder/", "?query=param")]
|
||||
public void ParseValidReleaseEntryLines(string releaseEntry, string fileName, long fileSize, string baseUrl, string query)
|
||||
{
|
||||
var fixture = ReleaseEntry.ParseReleaseEntry(releaseEntry);
|
||||
Assert.Equal(fileName, fixture.Filename);
|
||||
Assert.Equal(fileSize, fixture.Filesize);
|
||||
Assert.Equal(baseUrl, fixture.BaseUrl);
|
||||
Assert.Equal(query, fixture.Query);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(@"94689fede03fed7ab59c24337673a27837f0c3ec My.Cool.App-1.0-full.nupkg 1004502", "My.Cool.App")]
|
||||
[InlineData(@"94689fede03fed7ab59c24337673a27837f0c3ec My.Cool.App-1.1.nupkg 1004502", "My.Cool.App")]
|
||||
[InlineData(@"94689fede03fed7ab59c24337673a27837f0c3ec http://test.org/Folder/My.Cool.App-1.2.nupkg?query=param 1231953", "My.Cool.App")]
|
||||
public void ParseValidReleaseEntryLinesWithDots(string releaseEntry, string packageName)
|
||||
{
|
||||
var fixture = ReleaseEntry.ParseReleaseEntry(releaseEntry);
|
||||
Assert.Equal(packageName, fixture.PackageName);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(@"94689fede03fed7ab59c24337673a27837f0c3ec My-Cool-App-1.0-full.nupkg 1004502", "My-Cool-App")]
|
||||
[InlineData(@"94689fede03fed7ab59c24337673a27837f0c3ec My.Cool-App-1.1.nupkg 1004502", "My.Cool-App")]
|
||||
[InlineData(@"94689fede03fed7ab59c24337673a27837f0c3ec http://test.org/Folder/My.Cool-App-1.2.nupkg?query=param 1231953", "My.Cool-App")]
|
||||
public void ParseValidReleaseEntryLinesWithDashes(string releaseEntry, string packageName)
|
||||
{
|
||||
var fixture = ReleaseEntry.ParseReleaseEntry(releaseEntry);
|
||||
Assert.Equal(packageName, fixture.PackageName);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(@"0000000000000000000000000000000000000000 file:/C/Folder/MyCoolApp-0.0.nupkg 0")]
|
||||
[InlineData(@"0000000000000000000000000000000000000000 C:\Folder\MyCoolApp-0.0.nupkg 0")]
|
||||
[InlineData(@"0000000000000000000000000000000000000000 ..\OtherFolder\MyCoolApp-0.0.nupkg 0")]
|
||||
[InlineData(@"0000000000000000000000000000000000000000 ../OtherFolder/MyCoolApp-0.0.nupkg 0")]
|
||||
[InlineData(@"0000000000000000000000000000000000000000 \\Somewhere\NetworkShare\MyCoolApp-0.0.nupkg.delta 0")]
|
||||
public void ParseThrowsWhenInvalidReleaseEntryLines(string releaseEntry)
|
||||
{
|
||||
Assert.Throws<Exception>(() => ReleaseEntry.ParseReleaseEntry(releaseEntry));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(@"0000000000000000000000000000000000000000 file.nupkg 0")]
|
||||
[InlineData(@"0000000000000000000000000000000000000000 http://path/file.nupkg 0")]
|
||||
public void EntryAsStringMatchesParsedInput(string releaseEntry)
|
||||
{
|
||||
var fixture = ReleaseEntry.ParseReleaseEntry(releaseEntry);
|
||||
Assert.Equal(releaseEntry, fixture.EntryAsString);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("Squirrel.Core.1.0.0.0.nupkg", 4457, "75255cfd229a1ed1447abe1104f5635e69975d30")]
|
||||
[InlineData("Squirrel.Core.1.1.0.0.nupkg", 15830, "9baf1dbacb09940086c8c62d9a9dbe69fe1f7593")]
|
||||
public void GenerateFromFileTest(string name, long size, string sha1)
|
||||
{
|
||||
var path = IntegrationTestHelper.GetPath("fixtures", name);
|
||||
|
||||
using (var f = File.OpenRead(path)) {
|
||||
var fixture = ReleaseEntry.GenerateFromFile(f, "dontcare");
|
||||
Assert.Equal(size, fixture.Filesize);
|
||||
Assert.Equal(sha1, fixture.SHA1.ToLowerInvariant());
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("0000000000000000000000000000000000000000 MyCoolApp-1.2.nupkg 123", 1, 2, 0, 0, "", false)]
|
||||
[InlineData("0000000000000000000000000000000000000000 MyCoolApp-1.2-full.nupkg 123", 1, 2, 0, 0, "", false)]
|
||||
[InlineData("0000000000000000000000000000000000000000 MyCoolApp-1.2-delta.nupkg 123", 1, 2, 0, 0, "", true)]
|
||||
[InlineData("0000000000000000000000000000000000000000 MyCoolApp-1.2-beta1.nupkg 123", 1, 2, 0, 0, "beta1", false)]
|
||||
[InlineData("0000000000000000000000000000000000000000 MyCoolApp-1.2-beta1-full.nupkg 123", 1, 2, 0, 0, "beta1", false)]
|
||||
[InlineData("0000000000000000000000000000000000000000 MyCoolApp-1.2-beta1-delta.nupkg 123", 1, 2, 0, 0, "beta1", true)]
|
||||
[InlineData("0000000000000000000000000000000000000000 MyCoolApp-1.2.3.nupkg 123", 1, 2, 3, 0, "", false)]
|
||||
[InlineData("0000000000000000000000000000000000000000 MyCoolApp-1.2.3-full.nupkg 123", 1, 2, 3, 0, "", false)]
|
||||
[InlineData("0000000000000000000000000000000000000000 MyCoolApp-1.2.3-delta.nupkg 123", 1, 2, 3, 0, "", true)]
|
||||
[InlineData("0000000000000000000000000000000000000000 MyCoolApp-1.2.3-beta1.nupkg 123", 1, 2, 3, 0, "beta1", false)]
|
||||
[InlineData("0000000000000000000000000000000000000000 MyCoolApp-1.2.3-beta1-full.nupkg 123", 1, 2, 3, 0, "beta1", false)]
|
||||
[InlineData("0000000000000000000000000000000000000000 MyCoolApp-1.2.3-beta1-delta.nupkg 123", 1, 2, 3, 0, "beta1", true)]
|
||||
[InlineData("0000000000000000000000000000000000000000 MyCoolApp-1.2.3.4.nupkg 123", 1, 2, 3, 4, "", false)]
|
||||
[InlineData("0000000000000000000000000000000000000000 MyCoolApp-1.2.3.4-full.nupkg 123", 1, 2, 3, 4, "", false)]
|
||||
[InlineData("0000000000000000000000000000000000000000 MyCoolApp-1.2.3.4-delta.nupkg 123", 1, 2, 3, 4, "", true)]
|
||||
[InlineData("0000000000000000000000000000000000000000 MyCoolApp-1.2.3.4-beta1.nupkg 123", 1, 2, 3, 4, "beta1", false)]
|
||||
[InlineData("0000000000000000000000000000000000000000 MyCoolApp-1.2.3.4-beta1-full.nupkg 123", 1, 2, 3, 4, "beta1", false)]
|
||||
[InlineData("0000000000000000000000000000000000000000 MyCoolApp-1.2.3.4-beta1-delta.nupkg 123", 1, 2, 3, 4, "beta1", true)]
|
||||
public void ParseVersionTest(string releaseEntry, int major, int minor, int patch, int revision, string prerelease, bool isDelta)
|
||||
{
|
||||
var fixture = ReleaseEntry.ParseReleaseEntry(releaseEntry);
|
||||
|
||||
Assert.Equal(new NuGetVersion(major, minor, patch, revision, prerelease, null), fixture.Version);
|
||||
Assert.Equal(isDelta, fixture.IsDelta);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("0000000000000000000000000000000000000000 MyCool-App-1.2.nupkg 123", "MyCool-App")]
|
||||
[InlineData("0000000000000000000000000000000000000000 MyCool_App-1.2-full.nupkg 123", "MyCool_App")]
|
||||
[InlineData("0000000000000000000000000000000000000000 MyCoolApp-1.2-delta.nupkg 123", "MyCoolApp")]
|
||||
[InlineData("0000000000000000000000000000000000000000 MyCoolApp-1.2-beta1.nupkg 123", "MyCoolApp")]
|
||||
[InlineData("0000000000000000000000000000000000000000 MyCoolApp-1.2-beta1-full.nupkg 123", "MyCoolApp")]
|
||||
[InlineData("0000000000000000000000000000000000000000 MyCoolApp-1.2-beta1-delta.nupkg 123", "MyCoolApp")]
|
||||
[InlineData("0000000000000000000000000000000000000000 MyCool-App-1.2.3.nupkg 123", "MyCool-App")]
|
||||
[InlineData("0000000000000000000000000000000000000000 MyCool_App-1.2.3-full.nupkg 123", "MyCool_App")]
|
||||
[InlineData("0000000000000000000000000000000000000000 MyCoolApp-1.2.3-delta.nupkg 123", "MyCoolApp")]
|
||||
[InlineData("0000000000000000000000000000000000000000 MyCoolApp-1.2.3-beta1.nupkg 123", "MyCoolApp")]
|
||||
[InlineData("0000000000000000000000000000000000000000 MyCoolApp-1.2.3-beta1-full.nupkg 123", "MyCoolApp")]
|
||||
[InlineData("0000000000000000000000000000000000000000 MyCoolApp-1.2.3-beta1-delta.nupkg 123", "MyCoolApp")]
|
||||
[InlineData("0000000000000000000000000000000000000000 MyCool-App-1.2.3.4.nupkg 123", "MyCool-App")]
|
||||
[InlineData("0000000000000000000000000000000000000000 MyCool_App-1.2.3.4-full.nupkg 123", "MyCool_App")]
|
||||
[InlineData("0000000000000000000000000000000000000000 MyCoolApp-1.2.3.4-delta.nupkg 123", "MyCoolApp")]
|
||||
[InlineData("0000000000000000000000000000000000000000 MyCoolApp-1.2.3.4-beta1.nupkg 123", "MyCoolApp")]
|
||||
[InlineData("0000000000000000000000000000000000000000 MyCoolApp-1.2.3.4-beta1-full.nupkg 123", "MyCoolApp")]
|
||||
[InlineData("0000000000000000000000000000000000000000 MyCool-App-1.2.3.4-beta1-delta.nupkg 123", "MyCool-App")]
|
||||
public void CheckPackageName(string releaseEntry, string expected)
|
||||
{
|
||||
var fixture = ReleaseEntry.ParseReleaseEntry(releaseEntry);
|
||||
Assert.Equal(expected, fixture.PackageName);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("0000000000000000000000000000000000000000 MyCoolApp-1.2.nupkg 123 # 10%", 1, 2, 0, 0, "", false, 0.1f)]
|
||||
[InlineData("0000000000000000000000000000000000000000 MyCoolApp-1.2-full.nupkg 123 # 90%", 1, 2, 0, 0, "", false, 0.9f)]
|
||||
[InlineData("0000000000000000000000000000000000000000 MyCoolApp-1.2-delta.nupkg 123", 1, 2, 0, 0, "", true, null)]
|
||||
[InlineData("0000000000000000000000000000000000000000 MyCoolApp-1.2-delta.nupkg 123 # 5%", 1, 2, 0, 0, "", true, 0.05f)]
|
||||
public void ParseStagingPercentageTest(string releaseEntry, int major, int minor, int patch, int revision, string prerelease, bool isDelta, float? stagingPercentage)
|
||||
{
|
||||
var fixture = ReleaseEntry.ParseReleaseEntry(releaseEntry);
|
||||
|
||||
Assert.Equal(new NuGetVersion(major, minor, patch, revision, prerelease, null), fixture.Version);
|
||||
Assert.Equal(isDelta, fixture.IsDelta);
|
||||
|
||||
if (stagingPercentage.HasValue) {
|
||||
Assert.True(Math.Abs(fixture.StagingPercentage.Value - stagingPercentage.Value) < 0.001);
|
||||
} else {
|
||||
Assert.Null(fixture.StagingPercentage);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public void CanParseGeneratedReleaseEntryAsString()
|
||||
{
|
||||
var path = IntegrationTestHelper.GetPath("fixtures", "Squirrel.Core.1.1.0.0.nupkg");
|
||||
var entryAsString = ReleaseEntry.GenerateFromFile(path).EntryAsString;
|
||||
ReleaseEntry.ParseReleaseEntry(entryAsString);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void InvalidReleaseNotesThrowsException()
|
||||
{
|
||||
var path = IntegrationTestHelper.GetPath("fixtures", "Squirrel.Core.1.0.0.0.nupkg");
|
||||
var fixture = ReleaseEntry.GenerateFromFile(path);
|
||||
Assert.Throws<Exception>(() => fixture.GetReleaseNotes(IntegrationTestHelper.GetPath("fixtures")));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetLatestReleaseWithNullCollectionReturnsNull()
|
||||
{
|
||||
Assert.Null(ReleasePackageBuilder.GetPreviousRelease(
|
||||
null, null, null));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetLatestReleaseWithEmptyCollectionReturnsNull()
|
||||
{
|
||||
Assert.Null(ReleasePackageBuilder.GetPreviousRelease(
|
||||
Enumerable.Empty<ReleaseEntry>(), null, null));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WhenCurrentReleaseMatchesLastReleaseReturnNull()
|
||||
{
|
||||
var package = new ReleasePackageBuilder("Espera-1.7.6-beta.nupkg");
|
||||
|
||||
var releaseEntries = new[] {
|
||||
ReleaseEntry.ParseReleaseEntry(MockReleaseEntry("Espera-1.7.6-beta.nupkg"))
|
||||
};
|
||||
Assert.Null(ReleasePackageBuilder.GetPreviousRelease(
|
||||
releaseEntries, package, @"C:\temp\somefolder"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WhenMultipleReleaseMatchesReturnEarlierResult()
|
||||
{
|
||||
var expected = SemanticVersion.Parse("1.7.5-beta");
|
||||
var package = new ReleasePackageBuilder("Espera-1.7.6-beta.nupkg");
|
||||
|
||||
var releaseEntries = new[] {
|
||||
ReleaseEntry.ParseReleaseEntry(MockReleaseEntry("Espera-1.7.6-beta.nupkg")),
|
||||
ReleaseEntry.ParseReleaseEntry(MockReleaseEntry("Espera-1.7.5-beta.nupkg"))
|
||||
};
|
||||
|
||||
var actual = ReleasePackageBuilder.GetPreviousRelease(
|
||||
releaseEntries,
|
||||
package,
|
||||
@"C:\temp\");
|
||||
|
||||
Assert.Equal(expected, actual.Version);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WhenMultipleReleasesFoundReturnPreviousVersion()
|
||||
{
|
||||
var expected = SemanticVersion.Parse("1.7.6-beta");
|
||||
var input = new ReleasePackageBuilder("Espera-1.7.7-beta.nupkg");
|
||||
|
||||
var releaseEntries = new[] {
|
||||
ReleaseEntry.ParseReleaseEntry(MockReleaseEntry("Espera-1.7.6-beta.nupkg")),
|
||||
ReleaseEntry.ParseReleaseEntry(MockReleaseEntry("Espera-1.7.5-beta.nupkg"))
|
||||
};
|
||||
|
||||
var actual = ReleasePackageBuilder.GetPreviousRelease(
|
||||
releaseEntries,
|
||||
input,
|
||||
@"C:\temp\");
|
||||
|
||||
Assert.Equal(expected, actual.Version);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WhenMultipleReleasesFoundInOtherOrderReturnPreviousVersion()
|
||||
{
|
||||
var expected = SemanticVersion.Parse("1.7.6-beta");
|
||||
var input = new ReleasePackageBuilder("Espera-1.7.7-beta.nupkg");
|
||||
|
||||
var releaseEntries = new[] {
|
||||
ReleaseEntry.ParseReleaseEntry(MockReleaseEntry("Espera-1.7.5-beta.nupkg")),
|
||||
ReleaseEntry.ParseReleaseEntry(MockReleaseEntry("Espera-1.7.6-beta.nupkg"))
|
||||
};
|
||||
|
||||
var actual = ReleasePackageBuilder.GetPreviousRelease(
|
||||
releaseEntries,
|
||||
input,
|
||||
@"C:\temp\");
|
||||
|
||||
Assert.Equal(expected, actual.Version);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WhenReleasesAreOutOfOrderSortByVersion()
|
||||
{
|
||||
var path = Path.GetTempFileName();
|
||||
var firstVersion = SemanticVersion.Parse("1.0.0");
|
||||
var secondVersion = SemanticVersion.Parse("1.1.0");
|
||||
var thirdVersion = SemanticVersion.Parse("1.2.0");
|
||||
|
||||
var releaseEntries = new[] {
|
||||
ReleaseEntry.ParseReleaseEntry(MockReleaseEntry("Espera-1.2.0-delta.nupkg")),
|
||||
ReleaseEntry.ParseReleaseEntry(MockReleaseEntry("Espera-1.1.0-delta.nupkg")),
|
||||
ReleaseEntry.ParseReleaseEntry(MockReleaseEntry("Espera-1.1.0-full.nupkg")),
|
||||
ReleaseEntry.ParseReleaseEntry(MockReleaseEntry("Espera-1.2.0-full.nupkg")),
|
||||
ReleaseEntry.ParseReleaseEntry(MockReleaseEntry("Espera-1.0.0-full.nupkg"))
|
||||
};
|
||||
|
||||
ReleaseEntry.WriteReleaseFile(releaseEntries, path);
|
||||
|
||||
var releases = ReleaseEntry.ParseReleaseFile(File.ReadAllText(path)).ToArray();
|
||||
|
||||
Assert.Equal(firstVersion, releases[0].Version);
|
||||
Assert.Equal(secondVersion, releases[1].Version);
|
||||
Assert.Equal(true, releases[1].IsDelta);
|
||||
Assert.Equal(secondVersion, releases[2].Version);
|
||||
Assert.Equal(false, releases[2].IsDelta);
|
||||
Assert.Equal(thirdVersion, releases[3].Version);
|
||||
Assert.Equal(true, releases[3].IsDelta);
|
||||
Assert.Equal(thirdVersion, releases[4].Version);
|
||||
Assert.Equal(false, releases[4].IsDelta);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WhenPreReleasesAreOutOfOrderSortByNumericSuffixSemVer2()
|
||||
{
|
||||
var path = Path.GetTempFileName();
|
||||
var firstVersion = SemanticVersion.Parse("1.1.9-beta.105");
|
||||
var secondVersion = SemanticVersion.Parse("1.2.0-beta.9");
|
||||
var thirdVersion = SemanticVersion.Parse("1.2.0-beta.10");
|
||||
var fourthVersion = SemanticVersion.Parse("1.2.0-beta.100");
|
||||
|
||||
var releaseEntries = new[] {
|
||||
ReleaseEntry.ParseReleaseEntry(MockReleaseEntry("Espera-1.2.0-beta.1-full.nupkg")),
|
||||
ReleaseEntry.ParseReleaseEntry(MockReleaseEntry("Espera-1.2.0-beta.9-full.nupkg")),
|
||||
ReleaseEntry.ParseReleaseEntry(MockReleaseEntry("Espera-1.2.0-beta.100-full.nupkg")),
|
||||
ReleaseEntry.ParseReleaseEntry(MockReleaseEntry("Espera-1.1.9-beta.105-full.nupkg")),
|
||||
ReleaseEntry.ParseReleaseEntry(MockReleaseEntry("Espera-1.2.0-beta.10-full.nupkg"))
|
||||
};
|
||||
|
||||
ReleaseEntry.WriteReleaseFile(releaseEntries, path);
|
||||
|
||||
var releases = ReleaseEntry.ParseReleaseFile(File.ReadAllText(path)).ToArray();
|
||||
|
||||
Assert.Equal(firstVersion, releases[0].Version);
|
||||
Assert.Equal(secondVersion, releases[2].Version);
|
||||
Assert.Equal(thirdVersion, releases[3].Version);
|
||||
Assert.Equal(fourthVersion, releases[4].Version);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void StagingUsersGetBetaSoftware()
|
||||
{
|
||||
// NB: We're kind of using a hack here, in that we know that the
|
||||
// last 4 bytes are used as the percentage, and the percentage
|
||||
// effectively measures, "How close are you to zero". Guid.Empty
|
||||
// is v close to zero, because it is zero.
|
||||
var path = Path.GetTempFileName();
|
||||
var ourGuid = Guid.Empty;
|
||||
|
||||
var releaseEntries = new[] {
|
||||
ReleaseEntry.ParseReleaseEntry(MockReleaseEntry("Espera-1.2.0-full.nupkg", 0.1f)),
|
||||
ReleaseEntry.ParseReleaseEntry(MockReleaseEntry("Espera-1.1.0-full.nupkg")),
|
||||
ReleaseEntry.ParseReleaseEntry(MockReleaseEntry("Espera-1.0.0-full.nupkg"))
|
||||
};
|
||||
|
||||
ReleaseEntry.WriteReleaseFile(releaseEntries, path);
|
||||
|
||||
var releases = ReleaseEntry.ParseReleaseFileAndApplyStaging(File.ReadAllText(path), ourGuid).ToArray();
|
||||
Assert.Equal(3, releases.Length);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void BorkedUsersGetProductionSoftware()
|
||||
{
|
||||
var path = Path.GetTempFileName();
|
||||
var ourGuid = default(Guid?);
|
||||
|
||||
var releaseEntries = new[] {
|
||||
ReleaseEntry.ParseReleaseEntry(MockReleaseEntry("Espera-1.2.0-full.nupkg", 0.1f)),
|
||||
ReleaseEntry.ParseReleaseEntry(MockReleaseEntry("Espera-1.1.0-full.nupkg")),
|
||||
ReleaseEntry.ParseReleaseEntry(MockReleaseEntry("Espera-1.0.0-full.nupkg"))
|
||||
};
|
||||
|
||||
ReleaseEntry.WriteReleaseFile(releaseEntries, path);
|
||||
|
||||
var releases = ReleaseEntry.ParseReleaseFileAndApplyStaging(File.ReadAllText(path), ourGuid).ToArray();
|
||||
Assert.Equal(2, releases.Length);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("{22b29e6f-bd2e-43d2-85ca-ffffffffffff}")]
|
||||
[InlineData("{22b29e6f-bd2e-43d2-85ca-888888888888}")]
|
||||
[InlineData("{22b29e6f-bd2e-43d2-85ca-444444444444}")]
|
||||
public void UnluckyUsersGetProductionSoftware(string inputGuid)
|
||||
{
|
||||
var path = Path.GetTempFileName();
|
||||
var ourGuid = Guid.ParseExact(inputGuid, "B");
|
||||
|
||||
var releaseEntries = new[] {
|
||||
ReleaseEntry.ParseReleaseEntry(MockReleaseEntry("Espera-1.2.0-full.nupkg", 0.1f)),
|
||||
ReleaseEntry.ParseReleaseEntry(MockReleaseEntry("Espera-1.1.0-full.nupkg")),
|
||||
ReleaseEntry.ParseReleaseEntry(MockReleaseEntry("Espera-1.0.0-full.nupkg"))
|
||||
};
|
||||
|
||||
ReleaseEntry.WriteReleaseFile(releaseEntries, path);
|
||||
|
||||
var releases = ReleaseEntry.ParseReleaseFileAndApplyStaging(File.ReadAllText(path), ourGuid).ToArray();
|
||||
Assert.Equal(2, releases.Length);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("{22b29e6f-bd2e-43d2-85ca-333333333333}")]
|
||||
[InlineData("{22b29e6f-bd2e-43d2-85ca-111111111111}")]
|
||||
[InlineData("{22b29e6f-bd2e-43d2-85ca-000000000000}")]
|
||||
public void LuckyUsersGetBetaSoftware(string inputGuid)
|
||||
{
|
||||
var path = Path.GetTempFileName();
|
||||
var ourGuid = Guid.ParseExact(inputGuid, "B");
|
||||
|
||||
var releaseEntries = new[] {
|
||||
ReleaseEntry.ParseReleaseEntry(MockReleaseEntry("Espera-1.2.0-full.nupkg", 0.25f)),
|
||||
ReleaseEntry.ParseReleaseEntry(MockReleaseEntry("Espera-1.1.0-full.nupkg")),
|
||||
ReleaseEntry.ParseReleaseEntry(MockReleaseEntry("Espera-1.0.0-full.nupkg"))
|
||||
};
|
||||
|
||||
ReleaseEntry.WriteReleaseFile(releaseEntries, path);
|
||||
|
||||
var releases = ReleaseEntry.ParseReleaseFileAndApplyStaging(File.ReadAllText(path), ourGuid).ToArray();
|
||||
Assert.Equal(3, releases.Length);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ParseReleaseFileShouldReturnNothingForBlankFiles()
|
||||
{
|
||||
Assert.True(ReleaseEntry.ParseReleaseFile("").Count() == 0);
|
||||
Assert.True(ReleaseEntry.ParseReleaseFile(null).Count() == 0);
|
||||
}
|
||||
|
||||
static string MockReleaseEntry(string name, float? percentage = null)
|
||||
{
|
||||
if (percentage.HasValue) {
|
||||
var ret = String.Format("94689fede03fed7ab59c24337673a27837f0c3ec {0} 1004502 # {1:F0}%", name, percentage * 100.0f);
|
||||
return ret;
|
||||
} else {
|
||||
return String.Format("94689fede03fed7ab59c24337673a27837f0c3ec {0} 1004502", name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
180
test/Squirrel.Tests/ReleasePackageTests.cs
Normal file
180
test/Squirrel.Tests/ReleasePackageTests.cs
Normal file
@@ -0,0 +1,180 @@
|
||||
using System.Runtime.Versioning;
|
||||
using Squirrel.MarkdownSharp;
|
||||
using Squirrel;
|
||||
using Squirrel.Tests.TestHelpers;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Xml.Linq;
|
||||
using Squirrel.SimpleSplat;
|
||||
using Xunit;
|
||||
using Squirrel.NuGet;
|
||||
using Xunit.Abstractions;
|
||||
using NuGet.Versioning;
|
||||
using Squirrel.CommandLine;
|
||||
|
||||
namespace Squirrel.Tests
|
||||
{
|
||||
public class CreateReleasePackageTests : TestLoggingBase
|
||||
{
|
||||
public CreateReleasePackageTests(ITestOutputHelper log) : base(log)
|
||||
{
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("1.2.3")]
|
||||
[InlineData("1.2.3-alpha13")]
|
||||
[InlineData("1.2.3-alpha135")]
|
||||
[InlineData("0.0.1")]
|
||||
[InlineData("1.299656.3-alpha")]
|
||||
public void SemanticVersionParsesValidVersion(string ver)
|
||||
{
|
||||
NugetUtil.ThrowIfVersionNotSemverCompliant(ver);
|
||||
Assert.True(SemanticVersion.TryParse(ver, out var _));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("")]
|
||||
[InlineData("1")]
|
||||
[InlineData("0")]
|
||||
[InlineData("1.2.3.4")]
|
||||
[InlineData("1.2.3.4-alpha")]
|
||||
[InlineData("0.0.0.0")]
|
||||
[InlineData("0.0.0")]
|
||||
[InlineData("0.0")]
|
||||
[InlineData("0.0.0-alpha")]
|
||||
public void SemanticVersionThrowsInvalidVersion(string ver)
|
||||
{
|
||||
Assert.ThrowsAny<Exception>(() => NugetUtil.ThrowIfVersionNotSemverCompliant(ver));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ReleasePackageIntegrationTest()
|
||||
{
|
||||
var inputPackage = IntegrationTestHelper.GetPath("fixtures", "Squirrel.Tests.0.1.0-pre.nupkg");
|
||||
var outputPackage = Path.GetTempFileName() + ".nupkg";
|
||||
|
||||
var fixture = new ReleasePackageBuilder(inputPackage);
|
||||
|
||||
try {
|
||||
fixture.CreateReleasePackage(outputPackage);
|
||||
|
||||
this.Log().Info("Resulting package is at {0}", outputPackage);
|
||||
var pkg = new ZipPackage(outputPackage);
|
||||
|
||||
int refs = pkg.FrameworkAssemblies.Count();
|
||||
this.Log().Info("Found {0} refs", refs);
|
||||
refs.ShouldEqual(0);
|
||||
|
||||
this.Log().Info("Files in release package:");
|
||||
|
||||
List<ZipPackageFile> files = pkg.Files.ToList();
|
||||
files.ForEach(x => this.Log().Info(x.Path));
|
||||
|
||||
List<string> nonDesktopPaths = new[] { "sl", "winrt", "netcore", "win8", "windows8", "MonoAndroid", "MonoTouch", "MonoMac", "wp", }
|
||||
.Select(x => @"lib\" + x)
|
||||
.ToList();
|
||||
|
||||
files.Any(x => nonDesktopPaths.Any(y => x.Path.ToLowerInvariant().Contains(y.ToLowerInvariant()))).ShouldBeFalse();
|
||||
files.Any(x => x.Path.ToLowerInvariant().EndsWith(@".xml")).ShouldBeFalse();
|
||||
} finally {
|
||||
File.Delete(outputPackage);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CanLoadPackageWhichHasNoDependencies()
|
||||
{
|
||||
var inputPackage = IntegrationTestHelper.GetPath("fixtures", "Squirrel.Core.NoDependencies.1.0.0.0.nupkg");
|
||||
var outputPackage = Path.GetTempFileName() + ".nupkg";
|
||||
var fixture = new ReleasePackageBuilder(inputPackage);
|
||||
try {
|
||||
fixture.CreateReleasePackage(outputPackage);
|
||||
} finally {
|
||||
File.Delete(outputPackage);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ThrowsIfLoadsPackageWithDependencies()
|
||||
{
|
||||
var inputPackage = IntegrationTestHelper.GetPath("fixtures", "ProjectDependsOnJsonDotNet.1.0.nupkg");
|
||||
var outputPackage = Path.GetTempFileName() + ".nupkg";
|
||||
var fixture = new ReleasePackageBuilder(inputPackage);
|
||||
try {
|
||||
Assert.Throws<InvalidOperationException>(() => fixture.CreateReleasePackage(outputPackage));
|
||||
} finally {
|
||||
if (File.Exists(outputPackage))
|
||||
File.Delete(outputPackage);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SpecFileMarkdownRenderingTest()
|
||||
{
|
||||
var dontcare = IntegrationTestHelper.GetPath("fixtures", "Squirrel.Core.1.1.0.0.nupkg");
|
||||
var inputSpec = IntegrationTestHelper.GetPath("fixtures", "Squirrel.Core.1.1.0.0.nuspec");
|
||||
var fixture = new ReleasePackageBuilder(dontcare);
|
||||
|
||||
var targetFile = Path.GetTempFileName();
|
||||
File.Copy(inputSpec, targetFile, true);
|
||||
|
||||
try {
|
||||
var processor = new Func<string, string>(input =>
|
||||
(new Markdown()).Transform(input));
|
||||
|
||||
// NB: For No Reason At All, renderReleaseNotesMarkdown is
|
||||
// invulnerable to ExposedObject. Whyyyyyyyyy
|
||||
var renderMinfo = fixture.GetType().GetMethod("renderReleaseNotesMarkdown",
|
||||
BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
renderMinfo.Invoke(fixture, new object[] { targetFile, processor });
|
||||
|
||||
var doc = XDocument.Load(targetFile);
|
||||
XNamespace ns = "http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd";
|
||||
var relNotesElement = doc.Descendants(ns + "releaseNotes").First();
|
||||
var htmlText = relNotesElement.Value;
|
||||
|
||||
this.Log().Info("HTML Text:\n{0}", htmlText);
|
||||
|
||||
htmlText.Contains("## Release Notes").ShouldBeFalse();
|
||||
} finally {
|
||||
File.Delete(targetFile);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ContentFilesAreIncludedInCreatedPackage()
|
||||
{
|
||||
var inputPackage = IntegrationTestHelper.GetPath("fixtures", "ProjectWithContent.1.0.0.0-beta.nupkg");
|
||||
var outputPackage = Path.GetTempFileName() + ".zip";
|
||||
var fixture = new ReleasePackageBuilder(inputPackage);
|
||||
|
||||
try {
|
||||
fixture.CreateReleasePackage(outputPackage);
|
||||
|
||||
this.Log().Info("Resulting package is at {0}", outputPackage);
|
||||
var pkg = new ZipPackage(outputPackage);
|
||||
|
||||
int refs = pkg.FrameworkAssemblies.Count();
|
||||
this.Log().Info("Found {0} refs", refs);
|
||||
refs.ShouldEqual(0);
|
||||
|
||||
this.Log().Info("Files in release package:");
|
||||
|
||||
var contentFiles = pkg.Files.Where(f => f.IsContentFile()).ToArray();
|
||||
Assert.Equal(2, contentFiles.Count());
|
||||
|
||||
var contentFilePaths = contentFiles.Select(f => f.EffectivePath);
|
||||
|
||||
Assert.Contains("some-words.txt", contentFilePaths);
|
||||
Assert.Contains("dir\\item-in-subdirectory.txt", contentFilePaths);
|
||||
|
||||
Assert.Equal(1, pkg.Files.Where(f => f.IsLibFile()).Count());
|
||||
} finally {
|
||||
File.Delete(outputPackage);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
63
test/Squirrel.Tests/RuntimeTests.cs
Normal file
63
test/Squirrel.Tests/RuntimeTests.cs
Normal file
@@ -0,0 +1,63 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Xunit;
|
||||
|
||||
namespace Squirrel.Tests
|
||||
{
|
||||
public class RuntimeTests
|
||||
{
|
||||
// we are upgrading net6 to a minimum version of 6.0.2 to work
|
||||
// around a dotnet SDK bug right now.
|
||||
[Theory]
|
||||
[InlineData("net6", "net6.0.2-x64")]
|
||||
[InlineData("net6.0", "net6.0.2-x64")]
|
||||
[InlineData("net6-x64", "net6.0.2-x64")]
|
||||
[InlineData("net6-x86", "net6.0.2-x86")]
|
||||
[InlineData("net3.1", "netcoreapp3.1-x64")]
|
||||
[InlineData("netcoreapp3.1", "netcoreapp3.1-x64")]
|
||||
[InlineData("net3.1-x86", "netcoreapp3.1-x86")]
|
||||
[InlineData("net6.0.2", "net6.0.2-x64")]
|
||||
[InlineData("net6.0.2-x86", "net6.0.2-x86")]
|
||||
[InlineData("net6.0.1-x86", "net6.0.1-x86")]
|
||||
[InlineData("net6.0.0", "net6-x64")]
|
||||
public void DotnetParsesValidVersions(string input, string expected)
|
||||
{
|
||||
var p = Runtimes.DotnetInfo.Parse(input);
|
||||
Assert.Equal(expected, p.Id);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("net3.2")]
|
||||
[InlineData("net4.9")]
|
||||
[InlineData("net6.0.0.4")]
|
||||
public void DotnetParseThrowsInvalidVersion(string input)
|
||||
{
|
||||
Assert.ThrowsAny<Exception>(() => Runtimes.DotnetInfo.Parse(input));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("net6", true)]
|
||||
[InlineData("net20.0", true)]
|
||||
[InlineData("net5.0.14-x86", true)]
|
||||
[InlineData("netcoreapp3.1-x86", true)]
|
||||
[InlineData("net48", true)]
|
||||
[InlineData("netcoreapp4.8", false)]
|
||||
[InlineData("net4.8", false)]
|
||||
[InlineData("net2.5", false)]
|
||||
[InlineData("vcredist110-x64", true)]
|
||||
[InlineData("vcredist110-x86", true)]
|
||||
[InlineData("vcredist110", true)]
|
||||
[InlineData("vcredist143", true)]
|
||||
[InlineData("asd", false)]
|
||||
[InlineData("", false)]
|
||||
[InlineData(null, false)]
|
||||
public void GetRuntimeTests(string input, bool expected)
|
||||
{
|
||||
var dn = Runtimes.GetRuntimeByName(input);
|
||||
Assert.Equal(expected, dn != null);
|
||||
}
|
||||
}
|
||||
}
|
||||
29
test/Squirrel.Tests/Squirrel.Tests.csproj
Normal file
29
test/Squirrel.Tests/Squirrel.Tests.csproj
Normal file
@@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0-windows</TargetFramework>
|
||||
<Description>Squirrel.Tests</Description>
|
||||
<Title>Squirrel.Tests</Title>
|
||||
<IsPackable>false</IsPackable>
|
||||
<LangVersion>9</LangVersion>
|
||||
<IsTest>true</IsTest>
|
||||
<NoWarn>CS1998,xUnit2015,xUnit2017,xUnit2005,xUnit2009,xUnit2013,xUnit2004</NoWarn>
|
||||
<SignAssembly>True</SignAssembly>
|
||||
<AssemblyOriginatorKeyFile>..\..\Squirrel.snk</AssemblyOriginatorKeyFile>
|
||||
<NoWarn>$(NoWarn);CA2007</NoWarn>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.2.0" />
|
||||
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
|
||||
<PackageReference Include="xunit" Version="2.4.1" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5" PrivateAssets="All" />
|
||||
<PackageReference Include="System.IO.Packaging" Version="6.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\Squirrel.CommandLine\Squirrel.CommandLine.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
55
test/Squirrel.Tests/SquirrelAwareExecutableDetectorTests.cs
Normal file
55
test/Squirrel.Tests/SquirrelAwareExecutableDetectorTests.cs
Normal file
@@ -0,0 +1,55 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Squirrel.Tests.TestHelpers;
|
||||
using Xunit;
|
||||
|
||||
namespace Squirrel.Tests
|
||||
{
|
||||
public class SquirrelAwareExecutableDetectorTests
|
||||
{
|
||||
[Fact]
|
||||
public void AtomShellShouldBeSquirrelAware()
|
||||
{
|
||||
var target = IntegrationTestHelper.GetPath("fixtures", "atom.exe");
|
||||
|
||||
Assert.True(File.Exists(target));
|
||||
Assert.True(SquirrelAwareExecutableDetector.GetSquirrelAwareVersion(target) == 1);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SquirrelAwareViaLanguageNeutralVersionBlock()
|
||||
{
|
||||
var target = IntegrationTestHelper.GetPath("fixtures", "SquirrelAwareTweakedNetCoreApp.exe");
|
||||
Assert.True(File.Exists(target));
|
||||
|
||||
var ret = SquirrelAwareExecutableDetector.GetSquirrelAwareVersion(target);
|
||||
Assert.Equal(1, ret.Value);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NotSquirrelAwareTestAppShouldNotBeSquirrelAware()
|
||||
{
|
||||
var target = IntegrationTestHelper.GetPath("fixtures", "NotSquirrelAwareApp.exe");
|
||||
Assert.True(File.Exists(target));
|
||||
|
||||
Assert.Null(SquirrelAwareExecutableDetector.GetSquirrelAwareVersion(target));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SquirrelAwareViaManifest()
|
||||
{
|
||||
var target = IntegrationTestHelper.GetPath("fixtures", "PublishSingleFileAwareApp.exe");
|
||||
Assert.True(File.Exists(target));
|
||||
|
||||
var ret = SquirrelAwareExecutableDetector.GetSquirrelAwareVersion(target);
|
||||
Assert.Equal(1, ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
150
test/Squirrel.Tests/TestHelpers/AssertExtensions.cs
Normal file
150
test/Squirrel.Tests/TestHelpers/AssertExtensions.cs
Normal file
@@ -0,0 +1,150 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using Xunit;
|
||||
|
||||
namespace Squirrel.Tests.TestHelpers
|
||||
{
|
||||
public static class AssertExtensions
|
||||
{
|
||||
public static void ShouldBeAboutEqualTo(this DateTimeOffset expected, DateTimeOffset current)
|
||||
{
|
||||
Assert.Equal(expected.Date, current.Date);
|
||||
Assert.Equal(expected.Offset, current.Offset);
|
||||
Assert.Equal(expected.Hour, current.Hour);
|
||||
Assert.Equal(expected.Minute, current.Minute);
|
||||
Assert.Equal(expected.Second, current.Second);
|
||||
}
|
||||
|
||||
public static void ShouldBeFalse(this bool currentObject)
|
||||
{
|
||||
Assert.False(currentObject);
|
||||
}
|
||||
|
||||
public static void ShouldBeNull(this object currentObject)
|
||||
{
|
||||
Assert.Null(currentObject);
|
||||
}
|
||||
|
||||
public static void ShouldBeEmpty(this IEnumerable items)
|
||||
{
|
||||
Assert.Empty(items);
|
||||
}
|
||||
|
||||
public static void ShouldNotBeEmpty(this IEnumerable items)
|
||||
{
|
||||
Assert.NotEmpty(items);
|
||||
}
|
||||
|
||||
public static void ShouldBeTrue(this bool currentObject)
|
||||
{
|
||||
Assert.True(currentObject);
|
||||
}
|
||||
|
||||
public static void ShouldEqual(this object compareFrom, object compareTo)
|
||||
{
|
||||
Assert.Equal(compareTo, compareFrom);
|
||||
}
|
||||
|
||||
public static void ShouldEqual<T>(this T compareFrom, T compareTo)
|
||||
{
|
||||
Assert.Equal(compareTo, compareFrom);
|
||||
}
|
||||
|
||||
public static void ShouldBeSameAs<T>(this T actual, T expected)
|
||||
{
|
||||
Assert.Same(expected, actual);
|
||||
}
|
||||
|
||||
public static void ShouldNotBeSameAs<T>(this T actual, T expected)
|
||||
{
|
||||
Assert.NotSame(expected, actual);
|
||||
}
|
||||
|
||||
public static void ShouldBeAssignableFrom<T>(this object instance) where T : class
|
||||
{
|
||||
Assert.IsAssignableFrom<T>(instance);
|
||||
}
|
||||
|
||||
public static void ShouldBeType(this object instance, Type type)
|
||||
{
|
||||
Assert.IsType(type, instance);
|
||||
}
|
||||
|
||||
public static void ShouldBeType<T>(this object instance)
|
||||
{
|
||||
Assert.IsType<T>(instance);
|
||||
}
|
||||
|
||||
public static void ShouldNotBeType<T>(this object instance)
|
||||
{
|
||||
Assert.IsNotType<T>(instance);
|
||||
}
|
||||
|
||||
public static void ShouldContain(this string current, string expectedSubstring, StringComparison comparison)
|
||||
{
|
||||
Assert.Contains(expectedSubstring, current, comparison);
|
||||
}
|
||||
|
||||
public static void ShouldStartWith(this string current, string expectedSubstring, StringComparison comparison)
|
||||
{
|
||||
Assert.True(current.StartsWith(expectedSubstring, comparison));
|
||||
}
|
||||
|
||||
public static void ShouldNotBeNull(this object currentObject)
|
||||
{
|
||||
Assert.NotNull(currentObject);
|
||||
}
|
||||
|
||||
public static void ShouldNotBeNullNorEmpty(this string value)
|
||||
{
|
||||
Assert.NotNull(value);
|
||||
Assert.NotEmpty(value);
|
||||
}
|
||||
|
||||
public static void ShouldNotEqual(this object compareFrom, object compareTo)
|
||||
{
|
||||
Assert.NotEqual(compareTo, compareFrom);
|
||||
}
|
||||
|
||||
public static void ShouldBeGreaterThan<T>(this T current, T other) where T : IComparable
|
||||
{
|
||||
Assert.True(current.CompareTo(other) > 0, current + " is not greater than " + other);
|
||||
}
|
||||
|
||||
public static void ShouldBeLessThan<T>(this T current, T other) where T : IComparable
|
||||
{
|
||||
Assert.True(current.CompareTo(other) < 0, current + " is not less than " + other);
|
||||
}
|
||||
|
||||
static string ToSafeString(this char c)
|
||||
{
|
||||
if (Char.IsControl(c) || Char.IsWhiteSpace(c)) {
|
||||
switch (c) {
|
||||
case '\r':
|
||||
return @"\r";
|
||||
case '\n':
|
||||
return @"\n";
|
||||
case '\t':
|
||||
return @"\t";
|
||||
case '\a':
|
||||
return @"\a";
|
||||
case '\v':
|
||||
return @"\v";
|
||||
case '\f':
|
||||
return @"\f";
|
||||
default:
|
||||
return String.Format("\\u{0:X};", (int) c);
|
||||
}
|
||||
}
|
||||
return c.ToString(CultureInfo.InvariantCulture);
|
||||
}
|
||||
}
|
||||
|
||||
public enum DiffStyle
|
||||
{
|
||||
Full,
|
||||
Minimal
|
||||
}
|
||||
}
|
||||
138
test/Squirrel.Tests/TestHelpers/ExposedClass.cs
Normal file
138
test/Squirrel.Tests/TestHelpers/ExposedClass.cs
Normal file
@@ -0,0 +1,138 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Dynamic;
|
||||
using System.Reflection;
|
||||
|
||||
// Lovingly stolen from http://exposedobject.codeplex.com/
|
||||
|
||||
namespace Squirrel.Tests.TestHelpers
|
||||
{
|
||||
public class ExposedClass : DynamicObject
|
||||
{
|
||||
private Type m_type;
|
||||
private Dictionary<string, Dictionary<int, List<MethodInfo>>> m_staticMethods;
|
||||
private Dictionary<string, Dictionary<int, List<MethodInfo>>> m_genStaticMethods;
|
||||
|
||||
private ExposedClass(Type type)
|
||||
{
|
||||
m_type = type;
|
||||
|
||||
m_staticMethods =
|
||||
m_type
|
||||
.GetMethods(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static)
|
||||
.Where(m => !m.IsGenericMethod)
|
||||
.GroupBy(m => m.Name)
|
||||
.ToDictionary(
|
||||
p => p.Key,
|
||||
p => p.GroupBy(r => r.GetParameters().Length).ToDictionary(r => r.Key, r => r.ToList()));
|
||||
|
||||
m_genStaticMethods =
|
||||
m_type
|
||||
.GetMethods(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static)
|
||||
.Where(m => m.IsGenericMethod)
|
||||
.GroupBy(m => m.Name)
|
||||
.ToDictionary(
|
||||
p => p.Key,
|
||||
p => p.GroupBy(r => r.GetParameters().Length).ToDictionary(r => r.Key, r => r.ToList()));
|
||||
}
|
||||
|
||||
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
|
||||
{
|
||||
// Get type args of the call
|
||||
Type[] typeArgs = ExposedObjectHelper.GetTypeArgs(binder);
|
||||
if (typeArgs != null && typeArgs.Length == 0) typeArgs = null;
|
||||
|
||||
//
|
||||
// Try to call a non-generic instance method
|
||||
//
|
||||
if (typeArgs == null
|
||||
&& m_staticMethods.ContainsKey(binder.Name)
|
||||
&& m_staticMethods[binder.Name].ContainsKey(args.Length)
|
||||
&& ExposedObjectHelper.InvokeBestMethod(args, null, m_staticMethods[binder.Name][args.Length], out result))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
// Try to call a generic instance method
|
||||
//
|
||||
if (m_staticMethods.ContainsKey(binder.Name)
|
||||
&& m_staticMethods[binder.Name].ContainsKey(args.Length))
|
||||
{
|
||||
List<MethodInfo> methods = new List<MethodInfo>();
|
||||
|
||||
foreach (var method in m_genStaticMethods[binder.Name][args.Length])
|
||||
{
|
||||
if (method.GetGenericArguments().Length == typeArgs.Length)
|
||||
{
|
||||
methods.Add(method.MakeGenericMethod(typeArgs));
|
||||
}
|
||||
}
|
||||
|
||||
if (ExposedObjectHelper.InvokeBestMethod(args, null, methods, out result))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
result = null;
|
||||
return false;
|
||||
}
|
||||
public override bool TrySetMember(SetMemberBinder binder, object value)
|
||||
{
|
||||
var propertyInfo = m_type.GetProperty(
|
||||
binder.Name,
|
||||
BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static);
|
||||
|
||||
if (propertyInfo != null)
|
||||
{
|
||||
propertyInfo.SetValue(null, value, null);
|
||||
return true;
|
||||
}
|
||||
|
||||
var fieldInfo = m_type.GetField(
|
||||
binder.Name,
|
||||
BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static);
|
||||
|
||||
if (fieldInfo != null)
|
||||
{
|
||||
fieldInfo.SetValue(null, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool TryGetMember(GetMemberBinder binder, out object result)
|
||||
{
|
||||
var propertyInfo = m_type.GetProperty(
|
||||
binder.Name,
|
||||
BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static);
|
||||
|
||||
if (propertyInfo != null)
|
||||
{
|
||||
result = propertyInfo.GetValue(null, null);
|
||||
return true;
|
||||
}
|
||||
|
||||
var fieldInfo = m_type.GetField(
|
||||
binder.Name,
|
||||
BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static);
|
||||
|
||||
if (fieldInfo != null)
|
||||
{
|
||||
result = fieldInfo.GetValue(null);
|
||||
return true;
|
||||
}
|
||||
|
||||
result = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
public static dynamic From(Type type)
|
||||
{
|
||||
return new ExposedClass(type);
|
||||
}
|
||||
}
|
||||
}
|
||||
170
test/Squirrel.Tests/TestHelpers/ExposedObject.cs
Normal file
170
test/Squirrel.Tests/TestHelpers/ExposedObject.cs
Normal file
@@ -0,0 +1,170 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Dynamic;
|
||||
using System.Reflection;
|
||||
|
||||
// Lovingly stolen from http://exposedobject.codeplex.com/
|
||||
|
||||
namespace Squirrel.Tests.TestHelpers
|
||||
{
|
||||
public class ExposedObject : DynamicObject
|
||||
{
|
||||
private object m_object;
|
||||
private Type m_type;
|
||||
private Dictionary<string, Dictionary<int, List<MethodInfo>>> m_instanceMethods;
|
||||
private Dictionary<string, Dictionary<int, List<MethodInfo>>> m_genInstanceMethods;
|
||||
|
||||
private ExposedObject(object obj)
|
||||
{
|
||||
m_object = obj;
|
||||
m_type = obj.GetType();
|
||||
|
||||
m_instanceMethods =
|
||||
m_type
|
||||
.GetMethods(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance)
|
||||
.Where(m => !m.IsGenericMethod)
|
||||
.GroupBy(m => m.Name)
|
||||
.ToDictionary(
|
||||
p => p.Key,
|
||||
p => p.GroupBy(r => r.GetParameters().Length).ToDictionary(r => r.Key, r => r.ToList()));
|
||||
|
||||
m_genInstanceMethods =
|
||||
m_type
|
||||
.GetMethods(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance)
|
||||
.Where(m => m.IsGenericMethod)
|
||||
.GroupBy(m => m.Name)
|
||||
.ToDictionary(
|
||||
p => p.Key,
|
||||
p => p.GroupBy(r => r.GetParameters().Length).ToDictionary(r => r.Key, r => r.ToList()));
|
||||
}
|
||||
|
||||
public object Object { get { return m_object; } }
|
||||
|
||||
public static dynamic New<T>()
|
||||
{
|
||||
return New(typeof(T));
|
||||
}
|
||||
|
||||
public static dynamic New(Type type)
|
||||
{
|
||||
return new ExposedObject(Activator.CreateInstance(type));
|
||||
}
|
||||
|
||||
public static dynamic From(object obj)
|
||||
{
|
||||
return new ExposedObject(obj);
|
||||
}
|
||||
|
||||
public static T Cast<T>(ExposedObject t)
|
||||
{
|
||||
return (T)t.m_object;
|
||||
}
|
||||
|
||||
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
|
||||
{
|
||||
// Get type args of the call
|
||||
Type[] typeArgs = ExposedObjectHelper.GetTypeArgs(binder);
|
||||
if (typeArgs != null && typeArgs.Length == 0) typeArgs = null;
|
||||
|
||||
//
|
||||
// Try to call a non-generic instance method
|
||||
//
|
||||
if (typeArgs == null
|
||||
&& m_instanceMethods.ContainsKey(binder.Name)
|
||||
&& m_instanceMethods[binder.Name].ContainsKey(args.Length)
|
||||
&& ExposedObjectHelper.InvokeBestMethod(args, m_object, m_instanceMethods[binder.Name][args.Length], out result))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
// Try to call a generic instance method
|
||||
//
|
||||
if (m_instanceMethods.ContainsKey(binder.Name)
|
||||
&& m_instanceMethods[binder.Name].ContainsKey(args.Length))
|
||||
{
|
||||
List<MethodInfo> methods = new List<MethodInfo>();
|
||||
|
||||
if (m_genInstanceMethods.ContainsKey(binder.Name) &&
|
||||
m_genInstanceMethods[binder.Name].ContainsKey(args.Length))
|
||||
{
|
||||
foreach (var method in m_genInstanceMethods[binder.Name][args.Length])
|
||||
{
|
||||
if (method.GetGenericArguments().Length == typeArgs.Length)
|
||||
{
|
||||
methods.Add(method.MakeGenericMethod(typeArgs));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ExposedObjectHelper.InvokeBestMethod(args, m_object, methods, out result))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
result = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool TrySetMember(SetMemberBinder binder, object value)
|
||||
{
|
||||
var propertyInfo = m_type.GetProperty(
|
||||
binder.Name,
|
||||
BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
|
||||
|
||||
if (propertyInfo != null)
|
||||
{
|
||||
propertyInfo.SetValue(m_object, value, null);
|
||||
return true;
|
||||
}
|
||||
|
||||
var fieldInfo = m_type.GetField(
|
||||
binder.Name,
|
||||
BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
|
||||
|
||||
if (fieldInfo != null)
|
||||
{
|
||||
fieldInfo.SetValue(m_object, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool TryGetMember(GetMemberBinder binder, out object result)
|
||||
{
|
||||
var propertyInfo = m_object.GetType().GetProperty(
|
||||
binder.Name,
|
||||
BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
|
||||
|
||||
if (propertyInfo != null)
|
||||
{
|
||||
result = propertyInfo.GetValue(m_object, null);
|
||||
return true;
|
||||
}
|
||||
|
||||
var fieldInfo = m_object.GetType().GetField(
|
||||
binder.Name,
|
||||
BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
|
||||
|
||||
if (fieldInfo != null)
|
||||
{
|
||||
result = fieldInfo.GetValue(m_object);
|
||||
return true;
|
||||
}
|
||||
|
||||
result = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool TryConvert(ConvertBinder binder, out object result)
|
||||
{
|
||||
result = m_object;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
94
test/Squirrel.Tests/TestHelpers/ExposedObjectHelper.cs
Normal file
94
test/Squirrel.Tests/TestHelpers/ExposedObjectHelper.cs
Normal file
@@ -0,0 +1,94 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Dynamic;
|
||||
|
||||
// Lovingly stolen from http://exposedobject.codeplex.com/
|
||||
|
||||
namespace Squirrel.Tests.TestHelpers
|
||||
{
|
||||
internal class ExposedObjectHelper
|
||||
{
|
||||
private static Type s_csharpInvokePropertyType =
|
||||
typeof(Microsoft.CSharp.RuntimeBinder.RuntimeBinderException)
|
||||
.Assembly
|
||||
.GetType("Microsoft.CSharp.RuntimeBinder.ICSharpInvokeOrInvokeMemberBinder");
|
||||
|
||||
internal static bool InvokeBestMethod(object[] args, object target, List<MethodInfo> instanceMethods, out object result)
|
||||
{
|
||||
if (instanceMethods.Count == 1)
|
||||
{
|
||||
// Just one matching instance method - call it
|
||||
if (TryInvoke(instanceMethods[0], target, args, out result))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (instanceMethods.Count > 1)
|
||||
{
|
||||
// Find a method with best matching parameters
|
||||
MethodInfo best = null;
|
||||
Type[] bestParams = null;
|
||||
Type[] actualParams = args.Select(p => p == null ? typeof(object) : p.GetType()).ToArray();
|
||||
|
||||
Func<Type[], Type[], bool> isAssignableFrom = (a, b) =>
|
||||
{
|
||||
for (int i = 0; i < a.Length; i++)
|
||||
{
|
||||
if (!a[i].IsAssignableFrom(b[i])) return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
|
||||
foreach (var method in instanceMethods.Where(m => m.GetParameters().Length == args.Length))
|
||||
{
|
||||
Type[] mParams = method.GetParameters().Select(x => x.ParameterType).ToArray();
|
||||
if (isAssignableFrom(mParams, actualParams))
|
||||
{
|
||||
if (best == null || isAssignableFrom(bestParams, mParams))
|
||||
{
|
||||
best = method;
|
||||
bestParams = mParams;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (best != null && TryInvoke(best, target, args, out result))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
result = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
internal static bool TryInvoke(MethodInfo methodInfo, object target, object[] args, out object result)
|
||||
{
|
||||
try
|
||||
{
|
||||
result = methodInfo.Invoke(target, args);
|
||||
return true;
|
||||
}
|
||||
catch (TargetInvocationException) { }
|
||||
catch (TargetParameterCountException) { }
|
||||
|
||||
result = null;
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
internal static Type[] GetTypeArgs(InvokeMemberBinder binder)
|
||||
{
|
||||
if (s_csharpInvokePropertyType.IsInstanceOfType(binder))
|
||||
{
|
||||
PropertyInfo typeArgsProperty = s_csharpInvokePropertyType.GetProperty("TypeArguments");
|
||||
return ((IEnumerable<Type>)typeArgsProperty.GetValue(binder, null)).ToArray();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
42
test/Squirrel.Tests/TestHelpers/FakeDownloader.cs
Normal file
42
test/Squirrel.Tests/TestHelpers/FakeDownloader.cs
Normal file
@@ -0,0 +1,42 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Squirrel.Tests
|
||||
{
|
||||
public class FakeDownloader : Sources.IFileDownloader
|
||||
{
|
||||
public string LastUrl { get; private set; }
|
||||
public string LastLocalFile { get; private set; }
|
||||
public string LastAuthHeader { get; private set; }
|
||||
public string LastAcceptHeader { get; private set; }
|
||||
public byte[] MockedResponseBytes { get; set; } = new byte[0];
|
||||
public bool WriteMockLocalFile { get; set; } = false;
|
||||
|
||||
public Task<byte[]> DownloadBytes(string url, string auth, string acc)
|
||||
{
|
||||
LastUrl = url;
|
||||
LastAuthHeader = auth;
|
||||
LastAcceptHeader = acc;
|
||||
return Task.FromResult(MockedResponseBytes);
|
||||
}
|
||||
|
||||
public async Task DownloadFile(string url, string targetFile, Action<int> progress, string auth, string acc)
|
||||
{
|
||||
LastLocalFile = targetFile;
|
||||
var resp = await DownloadBytes(url, auth, acc);
|
||||
progress?.Invoke(25);
|
||||
progress?.Invoke(50);
|
||||
progress?.Invoke(75);
|
||||
progress?.Invoke(100);
|
||||
if (WriteMockLocalFile)
|
||||
File.WriteAllBytes(targetFile, resp);
|
||||
}
|
||||
|
||||
public async Task<string> DownloadString(string url, string auth, string acc)
|
||||
{
|
||||
return Encoding.UTF8.GetString(await DownloadBytes(url, auth, acc));
|
||||
}
|
||||
}
|
||||
}
|
||||
141
test/Squirrel.Tests/TestHelpers/IntegrationTestHelper.cs
Normal file
141
test/Squirrel.Tests/TestHelpers/IntegrationTestHelper.cs
Normal file
@@ -0,0 +1,141 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using Squirrel;
|
||||
using Squirrel.SimpleSplat;
|
||||
using Xunit;
|
||||
using System.Text;
|
||||
using SharpCompress.Archives.Zip;
|
||||
using SharpCompress.Readers;
|
||||
using SharpCompress.Common;
|
||||
using Squirrel.CommandLine;
|
||||
|
||||
namespace Squirrel.Tests.TestHelpers
|
||||
{
|
||||
public static class IntegrationTestHelper
|
||||
{
|
||||
public static string GetPath(params string[] paths)
|
||||
{
|
||||
var ret = GetIntegrationTestRootDirectory();
|
||||
return (new FileInfo(paths.Aggregate(ret, Path.Combine))).FullName;
|
||||
}
|
||||
|
||||
public static string GetIntegrationTestRootDirectory()
|
||||
{
|
||||
// XXX: This is an evil hack, but it's okay for a unit test
|
||||
// We can't use Assembly.Location because unit test runners love
|
||||
// to move stuff to temp directories
|
||||
var st = new StackFrame(true);
|
||||
var di = new DirectoryInfo(Path.Combine(Path.GetDirectoryName(st.GetFileName()), ".."));
|
||||
|
||||
return di.FullName;
|
||||
}
|
||||
|
||||
public static bool SkipTestOnXPAndVista()
|
||||
{
|
||||
int osVersion = Environment.OSVersion.Version.Major * 100 + Environment.OSVersion.Version.Minor;
|
||||
return (osVersion < 601);
|
||||
}
|
||||
|
||||
public static void RunBlockAsSTA(Action block)
|
||||
{
|
||||
Exception ex = null;
|
||||
var t = new Thread(() => {
|
||||
try {
|
||||
block();
|
||||
} catch (Exception e) {
|
||||
ex = e;
|
||||
}
|
||||
});
|
||||
|
||||
t.SetApartmentState(ApartmentState.STA);
|
||||
t.Start();
|
||||
t.Join();
|
||||
|
||||
if (ex != null) {
|
||||
// NB: If we don't do this, the test silently passes
|
||||
throw new Exception("", ex);
|
||||
}
|
||||
}
|
||||
|
||||
static object gate = 42;
|
||||
public static IDisposable WithFakeInstallDirectory(string packageFileName, out string path)
|
||||
{
|
||||
var ret = Utility.GetTempDirectory(out path);
|
||||
|
||||
File.Copy(GetPath("fixtures", packageFileName), Path.Combine(path, packageFileName));
|
||||
var rp = ReleaseEntry.GenerateFromFile(Path.Combine(path, packageFileName));
|
||||
ReleaseEntry.WriteReleaseFile(new[] { rp }, Path.Combine(path, "RELEASES"));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static string CreateFakeInstalledApp(string version, string outputDir, string nuspecFile = null)
|
||||
{
|
||||
var targetDir = default(string);
|
||||
|
||||
nuspecFile = nuspecFile ?? "SquirrelInstalledApp.nuspec";
|
||||
|
||||
using (var clearTemp = Utility.GetTempDirectory(out targetDir)) {
|
||||
var nuspec = File.ReadAllText(IntegrationTestHelper.GetPath("fixtures", nuspecFile), Encoding.UTF8);
|
||||
var nuspecPath = Path.Combine(targetDir, nuspecFile);
|
||||
|
||||
File.WriteAllText(nuspecPath, nuspec.Replace("0.1.0", version), Encoding.UTF8);
|
||||
|
||||
File.Copy(
|
||||
IntegrationTestHelper.GetPath("fixtures", "PublishSingleFileAwareApp.exe"),
|
||||
Path.Combine(targetDir, "SquirrelAwareApp.exe"));
|
||||
File.Copy(
|
||||
IntegrationTestHelper.GetPath("fixtures", "NotSquirrelAwareApp.exe"),
|
||||
Path.Combine(targetDir, "NotSquirrelAwareApp.exe"));
|
||||
|
||||
new NugetConsole().Pack(nuspecPath, targetDir, targetDir);
|
||||
|
||||
var di = new DirectoryInfo(targetDir);
|
||||
var pkg = di.EnumerateFiles("*.nupkg").First();
|
||||
|
||||
var targetPkgFile = Path.Combine(outputDir, pkg.Name);
|
||||
File.Copy(pkg.FullName, targetPkgFile);
|
||||
return targetPkgFile;
|
||||
}
|
||||
}
|
||||
|
||||
public static void CreateNewVersionInPackageDir(string version, string outputDir, string nuspecFile = null)
|
||||
{
|
||||
var pkgFile = CreateFakeInstalledApp(version, outputDir, nuspecFile);
|
||||
var pkgs = ReleaseEntry.BuildReleasesFile(outputDir);
|
||||
ReleaseEntry.WriteReleaseFile(pkgs, Path.Combine(outputDir, "RELEASES"));
|
||||
}
|
||||
|
||||
public static IDisposable WithFakeInstallDirectory(out string path)
|
||||
{
|
||||
return WithFakeInstallDirectory("SampleUpdatingApp.1.1.0.0.nupkg", out path);
|
||||
}
|
||||
|
||||
public static IDisposable WithFakeAlreadyInstalledApp(out string path)
|
||||
{
|
||||
return WithFakeAlreadyInstalledApp("InstalledSampleUpdatingApp-1.1.0.0.zip", out path);
|
||||
}
|
||||
|
||||
public static IDisposable WithFakeAlreadyInstalledApp(string zipFile, out string path)
|
||||
{
|
||||
var ret = Utility.GetTempDirectory(out path);
|
||||
|
||||
// NB: Apparently Ionic.Zip is perfectly content to extract a Zip
|
||||
// file that doesn't actually exist, without failing.
|
||||
var zipPath = GetPath("fixtures", zipFile);
|
||||
Assert.True(File.Exists(zipPath));
|
||||
|
||||
var opts = new ExtractionOptions() { ExtractFullPath = true, Overwrite = true, PreserveFileTime = true };
|
||||
using (var za = ZipArchive.Open(zipFile))
|
||||
using (var reader = za.ExtractAllEntries()) {
|
||||
reader.WriteEntryToDirectory(path, opts);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
49
test/Squirrel.Tests/TestHelpers/Logging.cs
Normal file
49
test/Squirrel.Tests/TestHelpers/Logging.cs
Normal file
@@ -0,0 +1,49 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Squirrel.SimpleSplat;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Squirrel.Tests
|
||||
{
|
||||
public interface ITestLogging
|
||||
{
|
||||
IFullLogger Log();
|
||||
}
|
||||
|
||||
public class TestLogger : ILogger
|
||||
{
|
||||
public LogLevel Level { get; set; }
|
||||
public ITestOutputHelper OutputHelper { get; }
|
||||
|
||||
public TestLogger(ITestOutputHelper outputHelper)
|
||||
{
|
||||
OutputHelper = outputHelper;
|
||||
}
|
||||
|
||||
public void Write([Localizable(false)] string message, LogLevel logLevel)
|
||||
{
|
||||
OutputHelper.WriteLine(message);
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class TestLoggingBase : ITestLogging
|
||||
{
|
||||
public ITestOutputHelper OutputHelper { get; }
|
||||
public IFullLogger Logger { get; }
|
||||
|
||||
public TestLoggingBase(ITestOutputHelper log)
|
||||
{
|
||||
OutputHelper = log;
|
||||
Logger = new WrappingFullLogger(new TestLogger(OutputHelper), typeof(TestLogger));
|
||||
}
|
||||
|
||||
public IFullLogger Log()
|
||||
{
|
||||
return Logger;
|
||||
}
|
||||
}
|
||||
}
|
||||
96
test/Squirrel.Tests/TestHelpers/StaticHttpServer.cs
Normal file
96
test/Squirrel.Tests/TestHelpers/StaticHttpServer.cs
Normal file
@@ -0,0 +1,96 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Squirrel.Tests
|
||||
{
|
||||
public sealed class StaticHttpServer : IDisposable
|
||||
{
|
||||
public int Port { get; private set; }
|
||||
public string RootPath { get; private set; }
|
||||
|
||||
IDisposable inner;
|
||||
|
||||
public StaticHttpServer(int port, string rootPath)
|
||||
{
|
||||
Port = port; RootPath = rootPath;
|
||||
}
|
||||
|
||||
public IDisposable Start()
|
||||
{
|
||||
if (inner != null) {
|
||||
throw new InvalidOperationException("Already started!");
|
||||
}
|
||||
|
||||
var server = new HttpListener();
|
||||
server.Prefixes.Add(String.Format("http://+:{0}/", Port));
|
||||
server.Start();
|
||||
|
||||
bool shouldStop = false;
|
||||
var listener = Task.Run(async () => {
|
||||
while (!shouldStop) {
|
||||
var ctx = await server.GetContextAsync();
|
||||
|
||||
if (ctx.Request.HttpMethod != "GET") {
|
||||
closeResponseWith(ctx, 400, "GETs only");
|
||||
return;
|
||||
}
|
||||
|
||||
var target = Path.Combine(RootPath, ctx.Request.Url.AbsolutePath.Replace('/', Path.DirectorySeparatorChar).Substring(1));
|
||||
var fi = new FileInfo(target);
|
||||
|
||||
if (!fi.FullName.StartsWith(RootPath)) {
|
||||
closeResponseWith(ctx, 401, "Not authorized");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!fi.Exists) {
|
||||
closeResponseWith(ctx, 404, "Not found");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
using (var input = File.OpenRead(target)) {
|
||||
ctx.Response.StatusCode = 200;
|
||||
input.CopyTo(ctx.Response.OutputStream);
|
||||
ctx.Response.Close();
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
closeResponseWith(ctx, 500, ex.ToString());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var ret = Disposable.Create(() => {
|
||||
shouldStop = true;
|
||||
server.Stop();
|
||||
listener.Wait(2000);
|
||||
|
||||
inner = null;
|
||||
});
|
||||
|
||||
inner = ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void closeResponseWith(HttpListenerContext ctx, int statusCode, string message)
|
||||
{
|
||||
ctx.Response.StatusCode = statusCode;
|
||||
using (var sw = new StreamWriter(ctx.Response.OutputStream, Encoding.UTF8)) {
|
||||
sw.WriteLine(message);
|
||||
}
|
||||
ctx.Response.Close();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
var toDispose = Interlocked.Exchange(ref inner, null);
|
||||
if (toDispose != null) {
|
||||
toDispose.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
41
test/Squirrel.Tests/TestHelpers/UpdateManagerTestImpl.cs
Normal file
41
test/Squirrel.Tests/TestHelpers/UpdateManagerTestImpl.cs
Normal file
@@ -0,0 +1,41 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using Squirrel.Sources;
|
||||
|
||||
namespace Squirrel.Tests.TestHelpers
|
||||
{
|
||||
class UpdateManagerTestImpl : UpdateManager
|
||||
{
|
||||
protected UpdateManagerTestImpl(IUpdateSource source, AppDesc config) : base(source, config)
|
||||
{
|
||||
}
|
||||
|
||||
public static UpdateManagerTestImpl FromLocalPackageTempDir(string updatePackageDir, string appId, string installTempDir)
|
||||
{
|
||||
var di = String.IsNullOrWhiteSpace(updatePackageDir) ? null : new DirectoryInfo(updatePackageDir);
|
||||
return FromLocalPackageTempDir(di, appId, installTempDir);
|
||||
}
|
||||
|
||||
public static UpdateManagerTestImpl FromLocalPackageTempDir(DirectoryInfo updatePackageDir, string appId, string installTempDir)
|
||||
{
|
||||
var appPath = Path.Combine(installTempDir, appId);
|
||||
Directory.CreateDirectory(appPath);
|
||||
var desc = new AppDescWindows(appPath, appId);
|
||||
return new UpdateManagerTestImpl(new SimpleFileSource(updatePackageDir), desc);
|
||||
}
|
||||
|
||||
public static UpdateManagerTestImpl FromFakeWebSource(string packageUrl, string appId, string installTempDir, IFileDownloader downloader = null)
|
||||
{
|
||||
var appPath = Path.Combine(installTempDir, appId);
|
||||
Directory.CreateDirectory(appPath);
|
||||
var desc = new AppDescWindows(appPath, appId);
|
||||
return new UpdateManagerTestImpl(new SimpleWebSource(packageUrl, downloader), desc);
|
||||
}
|
||||
|
||||
public Task<string> ApplyReleasesPublic(UpdateInfo updateInfo, bool silentInstall, bool attemptingFullInstall, Action<int> progress = null)
|
||||
{
|
||||
return this.ApplyReleases(updateInfo, silentInstall, attemptingFullInstall, progress);
|
||||
}
|
||||
}
|
||||
}
|
||||
367
test/Squirrel.Tests/UpdateManagerTests.cs
Normal file
367
test/Squirrel.Tests/UpdateManagerTests.cs
Normal file
@@ -0,0 +1,367 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Win32;
|
||||
using Squirrel;
|
||||
using Squirrel.Tests.TestHelpers;
|
||||
using Xunit;
|
||||
using System.Net;
|
||||
using Squirrel.NuGet;
|
||||
using System.Net.Http;
|
||||
using NuGet.Versioning;
|
||||
using Squirrel.Sources;
|
||||
|
||||
namespace Squirrel.Tests
|
||||
{
|
||||
public class UpdateManagerTests
|
||||
{
|
||||
public const string APP_ID = "theFakeApp";
|
||||
|
||||
public class CreateUninstallerRegKeyTests
|
||||
{
|
||||
[Fact]
|
||||
public async Task CallingMethodTwiceShouldUpdateInstaller()
|
||||
{
|
||||
using var _1 = Utility.GetTempDirectory(out var path);
|
||||
using var _2 = Utility.GetTempDirectory(out var remotePkgDir);
|
||||
|
||||
IntegrationTestHelper.CreateNewVersionInPackageDir("0.1.0", remotePkgDir);
|
||||
using (var fixture = UpdateManagerTestImpl.FromLocalPackageTempDir(remotePkgDir, APP_ID, path))
|
||||
await fixture.FullInstall();
|
||||
|
||||
using (var mgr = UpdateManagerTestImpl.FromLocalPackageTempDir(remotePkgDir, APP_ID, path)) {
|
||||
await mgr.CreateUninstallerRegistryEntry();
|
||||
var regKey = await mgr.CreateUninstallerRegistryEntry();
|
||||
|
||||
Assert.False(String.IsNullOrWhiteSpace((string) regKey.GetValue("DisplayName")));
|
||||
|
||||
mgr.RemoveUninstallerRegistryEntry();
|
||||
}
|
||||
|
||||
// NB: Squirrel-Aware first-run might still be running, slow
|
||||
// our roll before blowing away the temp path
|
||||
Thread.Sleep(1000);
|
||||
|
||||
var key = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Default)
|
||||
.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Uninstall");
|
||||
using (key) {
|
||||
Assert.False(key.GetSubKeyNames().Contains(APP_ID));
|
||||
}
|
||||
}
|
||||
|
||||
public class UpdateLocalReleasesTests
|
||||
{
|
||||
[Fact]
|
||||
public async Task UpdateLocalReleasesSmokeTest()
|
||||
{
|
||||
using var _1 = Utility.GetTempDirectory(out var tempDir);
|
||||
|
||||
var appDir = Path.Combine(tempDir, APP_ID);
|
||||
var packageDir = Directory.CreateDirectory(Path.Combine(appDir, "packages"));
|
||||
|
||||
new[] {
|
||||
"Squirrel.Core.1.0.0.0-full.nupkg",
|
||||
"Squirrel.Core.1.1.0.0-delta.nupkg",
|
||||
"Squirrel.Core.1.1.0.0-full.nupkg",
|
||||
}.ForEach(x => File.Copy(IntegrationTestHelper.GetPath("fixtures", x), Path.Combine(tempDir, APP_ID, "packages", x)));
|
||||
|
||||
var info = new AppDescWindows(appDir, APP_ID);
|
||||
ReleaseEntry.BuildReleasesFile(info.PackagesDir);
|
||||
|
||||
var releasePath = Path.Combine(packageDir.FullName, "RELEASES");
|
||||
File.Exists(releasePath).ShouldBeTrue();
|
||||
|
||||
var entries = ReleaseEntry.ParseReleaseFile(File.ReadAllText(releasePath, Encoding.UTF8));
|
||||
entries.Count().ShouldEqual(3);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task InitialInstallSmokeTest()
|
||||
{
|
||||
using var _1 = Utility.GetTempDirectory(out var tempDir);
|
||||
|
||||
var remotePackageDir = Directory.CreateDirectory(Path.Combine(tempDir, "remotePackages"));
|
||||
var localAppDir = Path.Combine(tempDir, APP_ID);
|
||||
|
||||
new[] {
|
||||
"Squirrel.Core.1.0.0.0-full.nupkg",
|
||||
}.ForEach(x => File.Copy(IntegrationTestHelper.GetPath("fixtures", x), Path.Combine(remotePackageDir.FullName, x)));
|
||||
|
||||
using var fixture = UpdateManagerTestImpl.FromLocalPackageTempDir(remotePackageDir.FullName, APP_ID, tempDir);
|
||||
await fixture.FullInstall();
|
||||
|
||||
var releasePath = Path.Combine(localAppDir, "packages", "RELEASES");
|
||||
File.Exists(releasePath).ShouldBeTrue();
|
||||
|
||||
var entries = ReleaseEntry.ParseReleaseFile(File.ReadAllText(releasePath, Encoding.UTF8));
|
||||
entries.Count().ShouldEqual(1);
|
||||
|
||||
Assert.True(File.Exists(Path.Combine(localAppDir, "current", "ReactiveUI.dll")));
|
||||
Assert.True(File.Exists(Path.Combine(localAppDir, "current", "NSync.Core.dll")));
|
||||
|
||||
var manifest = NuspecManifest.ParseFromFile(Path.Combine(localAppDir, "current", Utility.SpecVersionFileName));
|
||||
Assert.Equal(new NuGetVersion(1, 0, 0, 0), manifest.Version);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task SpecialCharactersInitialInstallTest()
|
||||
{
|
||||
using var _1 = Utility.GetTempDirectory(out var tempDir);
|
||||
|
||||
var remotePackageDir = Directory.CreateDirectory(Path.Combine(tempDir, "remotePackages"));
|
||||
var localAppDir = Path.Combine(tempDir, APP_ID);
|
||||
|
||||
new[] {
|
||||
"SpecialCharacters-0.1.0-full.nupkg",
|
||||
}.ForEach(x => File.Copy(IntegrationTestHelper.GetPath("fixtures", x), Path.Combine(remotePackageDir.FullName, x)));
|
||||
|
||||
using var fixture = UpdateManagerTestImpl.FromLocalPackageTempDir(remotePackageDir.FullName, APP_ID, tempDir);
|
||||
await fixture.FullInstall();
|
||||
|
||||
var releasePath = Path.Combine(localAppDir, "packages", "RELEASES");
|
||||
File.Exists(releasePath).ShouldBeTrue();
|
||||
|
||||
var entries = ReleaseEntry.ParseReleaseFile(File.ReadAllText(releasePath, Encoding.UTF8));
|
||||
entries.Count().ShouldEqual(1);
|
||||
|
||||
new[] {
|
||||
"file space name.txt"
|
||||
}.ForEach(x => File.Exists(Path.Combine(localAppDir, "current", x)).ShouldBeTrue());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task WhenBothFilesAreInSyncNoUpdatesAreApplied()
|
||||
{
|
||||
using var _1 = Utility.GetTempDirectory(out var tempDir);
|
||||
|
||||
var appDir = Path.Combine(tempDir, APP_ID);
|
||||
var localPackages = Path.Combine(appDir, "packages");
|
||||
var remotePackages = Path.Combine(tempDir, "releases");
|
||||
Directory.CreateDirectory(localPackages);
|
||||
Directory.CreateDirectory(remotePackages);
|
||||
|
||||
new[] {
|
||||
"Squirrel.Core.1.0.0.0-full.nupkg",
|
||||
"Squirrel.Core.1.1.0.0-delta.nupkg",
|
||||
"Squirrel.Core.1.1.0.0-full.nupkg",
|
||||
}.ForEach(x => {
|
||||
var path = IntegrationTestHelper.GetPath("fixtures", x);
|
||||
File.Copy(path, Path.Combine(localPackages, x));
|
||||
File.Copy(path, Path.Combine(remotePackages, x));
|
||||
});
|
||||
|
||||
// sync both release files
|
||||
var info = new AppDescWindows(appDir, APP_ID);
|
||||
ReleaseEntry.BuildReleasesFile(info.PackagesDir);
|
||||
ReleaseEntry.BuildReleasesFile(remotePackages);
|
||||
|
||||
// check for an update
|
||||
using var mgr = UpdateManagerTestImpl.FromLocalPackageTempDir(remotePackages, APP_ID, tempDir);
|
||||
UpdateInfo updateInfo = await mgr.CheckForUpdate();
|
||||
|
||||
Assert.NotNull(updateInfo);
|
||||
Assert.Empty(updateInfo.ReleasesToApply);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task WhenRemoteReleasesDoNotHaveDeltasNoUpdatesAreApplied()
|
||||
{
|
||||
using var _1 = Utility.GetTempDirectory(out var tempDir);
|
||||
|
||||
var appDir = Path.Combine(tempDir, APP_ID);
|
||||
var localPackages = Path.Combine(appDir, "packages");
|
||||
var remotePackages = Path.Combine(tempDir, "releases");
|
||||
Directory.CreateDirectory(localPackages);
|
||||
Directory.CreateDirectory(remotePackages);
|
||||
|
||||
new[] {
|
||||
"Squirrel.Core.1.0.0.0-full.nupkg",
|
||||
"Squirrel.Core.1.1.0.0-delta.nupkg",
|
||||
"Squirrel.Core.1.1.0.0-full.nupkg",
|
||||
}.ForEach(x => {
|
||||
var path = IntegrationTestHelper.GetPath("fixtures", x);
|
||||
File.Copy(path, Path.Combine(localPackages, x));
|
||||
});
|
||||
|
||||
new[] {
|
||||
"Squirrel.Core.1.0.0.0-full.nupkg",
|
||||
"Squirrel.Core.1.1.0.0-full.nupkg",
|
||||
}.ForEach(x => {
|
||||
var path = IntegrationTestHelper.GetPath("fixtures", x);
|
||||
File.Copy(path, Path.Combine(remotePackages, x));
|
||||
});
|
||||
|
||||
// sync both release files
|
||||
var info = new AppDescWindows(appDir, APP_ID);
|
||||
ReleaseEntry.BuildReleasesFile(info.PackagesDir);
|
||||
ReleaseEntry.BuildReleasesFile(remotePackages);
|
||||
|
||||
using var mgr = UpdateManagerTestImpl.FromLocalPackageTempDir(remotePackages, APP_ID, tempDir);
|
||||
UpdateInfo updateInfo = await mgr.CheckForUpdate();
|
||||
|
||||
Assert.NotNull(updateInfo);
|
||||
Assert.Empty(updateInfo.ReleasesToApply);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task WhenTwoRemoteUpdatesAreAvailableChoosesDeltaVersion()
|
||||
{
|
||||
using var _1 = Utility.GetTempDirectory(out var tempDir);
|
||||
|
||||
var appDir = Path.Combine(tempDir, APP_ID);
|
||||
var localPackages = Path.Combine(appDir, "packages");
|
||||
var remotePackages = Path.Combine(tempDir, "releases");
|
||||
Directory.CreateDirectory(localPackages);
|
||||
Directory.CreateDirectory(remotePackages);
|
||||
|
||||
new[] { "Squirrel.Core.1.0.0.0-full.nupkg", }.ForEach(x => {
|
||||
var path = IntegrationTestHelper.GetPath("fixtures", x);
|
||||
File.Copy(path, Path.Combine(localPackages, x));
|
||||
});
|
||||
|
||||
new[] {
|
||||
"Squirrel.Core.1.0.0.0-full.nupkg",
|
||||
"Squirrel.Core.1.1.0.0-delta.nupkg",
|
||||
"Squirrel.Core.1.1.0.0-full.nupkg",
|
||||
}.ForEach(x => {
|
||||
var path = IntegrationTestHelper.GetPath("fixtures", x);
|
||||
File.Copy(path, Path.Combine(remotePackages, x));
|
||||
});
|
||||
|
||||
// sync both release files
|
||||
var info = new AppDescWindows(appDir, APP_ID);
|
||||
ReleaseEntry.BuildReleasesFile(info.PackagesDir);
|
||||
ReleaseEntry.BuildReleasesFile(remotePackages);
|
||||
|
||||
using var mgr = UpdateManagerTestImpl.FromLocalPackageTempDir(remotePackages, APP_ID, tempDir);
|
||||
UpdateInfo updateInfo = await mgr.CheckForUpdate();
|
||||
|
||||
Assert.True(updateInfo.ReleasesToApply.First().IsDelta);
|
||||
|
||||
updateInfo = await mgr.CheckForUpdate(ignoreDeltaUpdates: true);
|
||||
Assert.False(updateInfo.ReleasesToApply.First().IsDelta);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task WhenFolderDoesNotExistThrowHelpfulError()
|
||||
{
|
||||
using var _1 = Utility.GetTempDirectory(out var tempDir);
|
||||
var directory = Path.Combine(tempDir, "missing-folder");
|
||||
using var fixture = UpdateManagerTestImpl.FromLocalPackageTempDir(directory, APP_ID, tempDir);
|
||||
await Assert.ThrowsAsync<Exception>(() => fixture.CheckForUpdate());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task WhenReleasesFileDoesntExistThrowACustomError()
|
||||
{
|
||||
using var _1 = Utility.GetTempDirectory(out var tempDir);
|
||||
var directory = Path.Combine(tempDir, "folder");
|
||||
Directory.CreateDirectory(directory);
|
||||
using var fixture = UpdateManagerTestImpl.FromLocalPackageTempDir(directory, APP_ID, tempDir);
|
||||
await Assert.ThrowsAsync<Exception>(() => fixture.CheckForUpdate());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task WhenReleasesFileIsBlankThrowAnException()
|
||||
{
|
||||
using var _1 = Utility.GetTempDirectory(out var tempDir);
|
||||
var directory = Path.Combine(tempDir, "folder");
|
||||
Directory.CreateDirectory(directory);
|
||||
using var fixture = UpdateManagerTestImpl.FromLocalPackageTempDir(directory, APP_ID, tempDir);
|
||||
File.WriteAllText(Path.Combine(directory, "RELEASES"), "");
|
||||
await Assert.ThrowsAsync(typeof(Exception), () => fixture.CheckForUpdate());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task WhenUrlResultsInWebExceptionWeShouldThrow()
|
||||
{
|
||||
// This should result in a WebException (which gets caught) unless you can actually access http://lol
|
||||
using var _1 = Utility.GetTempDirectory(out var tempDir);
|
||||
using var fixture = UpdateManagerTestImpl.FromFakeWebSource("http://lol", APP_ID, tempDir);
|
||||
await Assert.ThrowsAsync(typeof(HttpRequestException), () => fixture.CheckForUpdate());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void IsInstalledHandlesInvalidDirectoryStructure()
|
||||
{
|
||||
using (Utility.GetTempDirectory(out var tempDir)) {
|
||||
Directory.CreateDirectory(Path.Combine(tempDir, APP_ID));
|
||||
Directory.CreateDirectory(Path.Combine(tempDir, APP_ID, "app-1.0.1"));
|
||||
Directory.CreateDirectory(Path.Combine(tempDir, APP_ID, "wrongDir"));
|
||||
File.WriteAllText(Path.Combine(tempDir, APP_ID, "Update.exe"), "1");
|
||||
using (var fixture = UpdateManagerTestImpl.FromFakeWebSource("http://lol", APP_ID, tempDir)) {
|
||||
Assert.Null(new AppDescWindows(Path.Combine(tempDir, "app.exe")).CurrentlyInstalledVersion);
|
||||
Assert.Null(new AppDescWindows(Path.Combine(tempDir, APP_ID, "app.exe")).CurrentlyInstalledVersion);
|
||||
Assert.Null(new AppDescWindows(Path.Combine(tempDir, APP_ID, "wrongDir", "app.exe")).CurrentlyInstalledVersion);
|
||||
Assert.Equal(new SemanticVersion(1, 0, 9),
|
||||
new AppDescWindows(Path.Combine(tempDir, APP_ID, "app-1.0.9", "app.exe")).CurrentlyInstalledVersion);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CurrentlyInstalledVersionDoesNotThrow()
|
||||
{
|
||||
using var fixture = new UpdateManager();
|
||||
Assert.Null(fixture.CurrentlyInstalledVersion());
|
||||
Assert.False(fixture.IsInstalledApp);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(0, 0, 25, 0)]
|
||||
[InlineData(12, 0, 25, 3)]
|
||||
[InlineData(55, 0, 25, 13)]
|
||||
[InlineData(100, 0, 25, 25)]
|
||||
[InlineData(0, 25, 50, 25)]
|
||||
[InlineData(12, 25, 50, 28)]
|
||||
[InlineData(55, 25, 50, 38)]
|
||||
[InlineData(100, 25, 50, 50)]
|
||||
public void CalculatesPercentageCorrectly(int percentageOfCurrentStep, int stepStartPercentage, int stepEndPercentage, int expectedPercentage)
|
||||
{
|
||||
var percentage = Utility.CalculateProgress(percentageOfCurrentStep, stepStartPercentage, stepEndPercentage);
|
||||
|
||||
Assert.Equal(expectedPercentage, percentage);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CalculatesPercentageCorrectlyForUpdateExe()
|
||||
{
|
||||
// Note: this mimicks the update.exe progress reporting of multiple steps
|
||||
|
||||
var progress = new List<int>();
|
||||
|
||||
// 3 % (3 stages), check for updates
|
||||
foreach (var step in new[] { 0, 33, 66, 100 }) {
|
||||
progress.Add(Utility.CalculateProgress(step, 0, 3));
|
||||
|
||||
Assert.InRange(progress.Last(), 0, 3);
|
||||
}
|
||||
|
||||
Assert.Equal(3, progress.Last());
|
||||
|
||||
// 3 - 30 %, download releases
|
||||
for (var step = 0; step <= 100; step++) {
|
||||
progress.Add(Utility.CalculateProgress(step, 3, 30));
|
||||
|
||||
Assert.InRange(progress.Last(), 3, 30);
|
||||
}
|
||||
|
||||
Assert.Equal(30, progress.Last());
|
||||
|
||||
// 30 - 100 %, apply releases
|
||||
for (var step = 0; step <= 100; step++) {
|
||||
progress.Add(Utility.CalculateProgress(step, 30, 100));
|
||||
|
||||
Assert.InRange(progress.Last(), 30, 100);
|
||||
}
|
||||
|
||||
Assert.Equal(100, progress.Last());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
256
test/Squirrel.Tests/UtilityTests.cs
Normal file
256
test/Squirrel.Tests/UtilityTests.cs
Normal file
@@ -0,0 +1,256 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using Squirrel.SimpleSplat;
|
||||
using Squirrel;
|
||||
using Squirrel.Tests.TestHelpers;
|
||||
using Xunit;
|
||||
using Squirrel.Shell;
|
||||
using System.Collections.Generic;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Squirrel.Tests
|
||||
{
|
||||
public class UtilityTests : TestLoggingBase
|
||||
{
|
||||
public UtilityTests(ITestOutputHelper log) : base(log)
|
||||
{
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("file.txt", "file.txt")]
|
||||
[InlineData("file", "file")]
|
||||
[InlineData("/file", "\\file")]
|
||||
[InlineData("/file/", "\\file")]
|
||||
[InlineData("one\\two\\..\\file", "one\\file")]
|
||||
[InlineData("C:/AnApp/file/", "C:\\AnApp\\file")]
|
||||
public void PathIsNormalized(string input, string expected)
|
||||
{
|
||||
var exp = Path.GetFullPath(expected);
|
||||
var normal = Utility.NormalizePath(input);
|
||||
Assert.Equal(exp, normal);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("C:\\AnApp", "C:\\AnApp\\file.exe", true)]
|
||||
[InlineData("C:\\AnApp\\", "C:\\AnApp\\file.exe", true)]
|
||||
[InlineData("C:\\AnApp", "C:\\AnApp\\sub\\dir\\file.exe", true)]
|
||||
[InlineData("C:\\AnApp\\", "C:\\AnApp\\sub\\dir\\file.exe", true)]
|
||||
[InlineData("C:\\AnAppTwo", "C:\\AnApp\\file.exe", false)]
|
||||
[InlineData("C:\\AnAppTwo\\", "C:\\AnApp\\file.exe", false)]
|
||||
[InlineData("C:\\AnAppTwo", "C:\\AnApp\\sub\\dir\\file.exe", false)]
|
||||
[InlineData("C:\\AnAppTwo\\", "C:\\AnApp\\sub\\dir\\file.exe", false)]
|
||||
[InlineData("AnAppThree", "AnAppThree\\file.exe", true)]
|
||||
public void FileIsInDirectory(string directory, string file, bool isIn)
|
||||
{
|
||||
var fileInDir = Utility.IsFileInDirectory(file, directory);
|
||||
Assert.Equal(isIn, fileInDir);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SetAppIdOnShortcutTest()
|
||||
{
|
||||
var sl = new ShellLink() {
|
||||
Target = @"C:\Windows\Notepad.exe",
|
||||
Description = "It's Notepad",
|
||||
};
|
||||
|
||||
sl.SetAppUserModelId("org.anaïsbetts.test");
|
||||
var path = Path.GetFullPath(@".\test.lnk");
|
||||
sl.Save(path);
|
||||
|
||||
Console.WriteLine("Saved to " + path);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RemoveByteOrderMarkerIfPresent()
|
||||
{
|
||||
var utf32Be = new byte[] { 0x00, 0x00, 0xFE, 0xFF };
|
||||
var utf32Le = new byte[] { 0xFF, 0xFE, 0x00, 0x00 };
|
||||
var utf16Be = new byte[] { 0xFE, 0xFF };
|
||||
var utf16Le = new byte[] { 0xFF, 0xFE };
|
||||
var utf8 = new byte[] { 0xEF, 0xBB, 0xBF };
|
||||
|
||||
var utf32BeHelloWorld = combine(utf32Be, Encoding.UTF8.GetBytes("hello world"));
|
||||
var utf32LeHelloWorld = combine(utf32Le, Encoding.UTF8.GetBytes("hello world"));
|
||||
var utf16BeHelloWorld = combine(utf16Be, Encoding.UTF8.GetBytes("hello world"));
|
||||
var utf16LeHelloWorld = combine(utf16Le, Encoding.UTF8.GetBytes("hello world"));
|
||||
var utf8HelloWorld = combine(utf8, Encoding.UTF8.GetBytes("hello world"));
|
||||
|
||||
var asciiMultipleChars = Encoding.ASCII.GetBytes("hello world");
|
||||
var asciiSingleChar = Encoding.ASCII.GetBytes("A");
|
||||
|
||||
var emptyString = string.Empty;
|
||||
string nullString = null;
|
||||
byte[] nullByteArray = { };
|
||||
Assert.Equal(string.Empty, Utility.RemoveByteOrderMarkerIfPresent(emptyString));
|
||||
Assert.Equal(string.Empty, Utility.RemoveByteOrderMarkerIfPresent(nullString));
|
||||
Assert.Equal(string.Empty, Utility.RemoveByteOrderMarkerIfPresent(nullByteArray));
|
||||
|
||||
Assert.Equal(string.Empty, Utility.RemoveByteOrderMarkerIfPresent(utf32Be));
|
||||
Assert.Equal(string.Empty, Utility.RemoveByteOrderMarkerIfPresent(utf32Le));
|
||||
Assert.Equal(string.Empty, Utility.RemoveByteOrderMarkerIfPresent(utf16Be));
|
||||
Assert.Equal(string.Empty, Utility.RemoveByteOrderMarkerIfPresent(utf16Le));
|
||||
Assert.Equal(string.Empty, Utility.RemoveByteOrderMarkerIfPresent(utf8));
|
||||
|
||||
Assert.Equal("hello world", Utility.RemoveByteOrderMarkerIfPresent(utf32BeHelloWorld));
|
||||
Assert.Equal("hello world", Utility.RemoveByteOrderMarkerIfPresent(utf32LeHelloWorld));
|
||||
Assert.Equal("hello world", Utility.RemoveByteOrderMarkerIfPresent(utf16BeHelloWorld));
|
||||
Assert.Equal("hello world", Utility.RemoveByteOrderMarkerIfPresent(utf16LeHelloWorld));
|
||||
Assert.Equal("hello world", Utility.RemoveByteOrderMarkerIfPresent(utf8HelloWorld));
|
||||
|
||||
Assert.Equal("hello world", Utility.RemoveByteOrderMarkerIfPresent(asciiMultipleChars));
|
||||
Assert.Equal("A", Utility.RemoveByteOrderMarkerIfPresent(asciiSingleChar));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ShaCheckShouldBeCaseInsensitive()
|
||||
{
|
||||
var sha1FromExternalTool = "75255cfd229a1ed1447abe1104f5635e69975d30";
|
||||
var inputPackage = IntegrationTestHelper.GetPath("fixtures", "Squirrel.Core.1.0.0.0.nupkg");
|
||||
var stream = File.OpenRead(inputPackage);
|
||||
var sha1 = Utility.CalculateStreamSHA1(stream);
|
||||
|
||||
Assert.NotEqual(sha1FromExternalTool, sha1);
|
||||
Assert.Equal(sha1FromExternalTool, sha1, StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CanDeleteDeepRecursiveDirectoryStructure()
|
||||
{
|
||||
string tempDir;
|
||||
using (Utility.GetTempDirectory(out tempDir)) {
|
||||
for (var i = 0; i < 50; i++) {
|
||||
var directory = Path.Combine(tempDir, newId());
|
||||
CreateSampleDirectory(directory);
|
||||
}
|
||||
|
||||
var files = Directory.GetFiles(tempDir, "*", SearchOption.AllDirectories);
|
||||
|
||||
var count = files.Count();
|
||||
|
||||
this.Log().Info("Created {0} files under directory {1}", count, tempDir);
|
||||
|
||||
var sw = new Stopwatch();
|
||||
sw.Start();
|
||||
Utility.DeleteFileOrDirectoryHard(tempDir);
|
||||
sw.Stop();
|
||||
this.Log().Info("Delete took {0}ms", sw.ElapsedMilliseconds);
|
||||
|
||||
Assert.False(Directory.Exists(tempDir));
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CreateFakePackageSmokeTest()
|
||||
{
|
||||
string path;
|
||||
using (Utility.GetTempDirectory(out path)) {
|
||||
var output = IntegrationTestHelper.CreateFakeInstalledApp("0.3.0", path);
|
||||
Assert.True(File.Exists(output));
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("foo.dll", true)]
|
||||
[InlineData("foo.DlL", true)]
|
||||
[InlineData("C:\\Foo\\Bar\\foo.Exe", true)]
|
||||
[InlineData("Test.png", false)]
|
||||
[InlineData(".rels", false)]
|
||||
public void FileIsLikelyPEImageTest(string input, bool result)
|
||||
{
|
||||
Assert.Equal(result, Utility.FileIsLikelyPEImage(input));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("C:\\Users\\bob\\temp\\pkgPath\\lib\\net45\\foo.exe", "C:\\Users\\bob\\temp\\pkgPath", true)]
|
||||
[InlineData("C:\\Users\\bob\\temp\\pkgPath\\lib\\net45\\node_modules\\foo.exe", "C:\\Users\\bob\\temp\\pkgPath", false)]
|
||||
[InlineData("C:\\Users\\bob\\temp\\pkgPath\\lib\\net45\\node_modules\\foo\\foo.exe", "C:\\Users\\bob\\temp\\pkgPath", false)]
|
||||
[InlineData("foo.png", "C:\\Users\\bob\\temp\\pkgPath", false)]
|
||||
public void IsFileTopLevelInPackageTest(string input, string packagePath, bool result)
|
||||
{
|
||||
Assert.Equal(result, Utility.IsFileTopLevelInPackage(input, packagePath));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WeCanFetchAllProcesses()
|
||||
{
|
||||
var result = PlatformUtil.GetRunningProcesses();
|
||||
Assert.True(result.Count > 1);
|
||||
Assert.True(result.Count != 2048);
|
||||
}
|
||||
|
||||
[Fact(Skip = "Only really need to run this test after changes to FileDownloader")]
|
||||
public void DownloaderReportsProgress()
|
||||
{
|
||||
// this probably should use a local http server instead.
|
||||
const string testUrl = "http://speedtest.tele2.net/1MB.zip";
|
||||
|
||||
var dl = Utility.CreateDefaultDownloader();
|
||||
|
||||
List<int> prog = new List<int>();
|
||||
using (Utility.GetTempFileName(out var tempPath))
|
||||
dl.DownloadFile(testUrl, tempPath, prog.Add).Wait();
|
||||
|
||||
Assert.True(prog.Count > 10);
|
||||
Assert.Equal(100, prog.Last());
|
||||
Assert.True(prog[1] != 0);
|
||||
}
|
||||
|
||||
static void CreateSampleDirectory(string directory)
|
||||
{
|
||||
Random prng = new Random();
|
||||
while (true) {
|
||||
Directory.CreateDirectory(directory);
|
||||
|
||||
for (var j = 0; j < 100; j++) {
|
||||
var file = Path.Combine(directory, newId());
|
||||
if (file.Length > 260) continue;
|
||||
File.WriteAllText(file, Guid.NewGuid().ToString());
|
||||
}
|
||||
|
||||
if (prng.NextDouble() > 0.5) {
|
||||
var childDirectory = Path.Combine(directory, newId());
|
||||
if (childDirectory.Length > 248) return;
|
||||
directory = childDirectory;
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static string newId()
|
||||
{
|
||||
var text = Guid.NewGuid().ToString();
|
||||
var bytes = Encoding.Unicode.GetBytes(text);
|
||||
var provider = SHA1.Create();
|
||||
var hashString = string.Empty;
|
||||
|
||||
foreach (var x in provider.ComputeHash(bytes)) {
|
||||
hashString += String.Format("{0:x2}", x);
|
||||
}
|
||||
|
||||
if (hashString.Length > 7) {
|
||||
return hashString.Substring(0, 7);
|
||||
}
|
||||
|
||||
return hashString;
|
||||
}
|
||||
|
||||
static byte[] combine(params byte[][] arrays)
|
||||
{
|
||||
var rv = new byte[arrays.Sum(a => a.Length)];
|
||||
var offset = 0;
|
||||
foreach (var array in arrays) {
|
||||
Buffer.BlockCopy(array, 0, rv, offset, array.Length);
|
||||
offset += array.Length;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
127
test/Squirrel.Tests/ZipPackageTests.cs
Normal file
127
test/Squirrel.Tests/ZipPackageTests.cs
Normal file
@@ -0,0 +1,127 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.IO.Packaging;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using NuGet.Versioning;
|
||||
using Squirrel.NuGet;
|
||||
using Squirrel.Tests.TestHelpers;
|
||||
using Xunit;
|
||||
using ZipPackage = Squirrel.NuGet.ZipPackage;
|
||||
|
||||
namespace Squirrel.Tests
|
||||
{
|
||||
public class ZipPackageTests
|
||||
{
|
||||
[Fact]
|
||||
public void HasSameFilesAndDependenciesAsPackaging()
|
||||
{
|
||||
using var _1 = Utility.GetTempDirectory(out var tempDir);
|
||||
var inputPackage = IntegrationTestHelper.GetPath("fixtures", "slack-1.1.8-full.nupkg");
|
||||
var copyPackage = Path.Combine(tempDir, "slack-1.1.8-full.nupkg");
|
||||
File.Copy(inputPackage, copyPackage);
|
||||
|
||||
var zp = new ZipPackage(inputPackage);
|
||||
var zipfw = zp.Frameworks;
|
||||
var zipf = zp.Files.OrderBy(f => f.Path).ToArray();
|
||||
var zipfLib = zp.Files.Where(f => f.IsLibFile()).OrderBy(f => f.Path).ToArray();
|
||||
|
||||
using Package package = Package.Open(copyPackage);
|
||||
var packagingfw = GetSupportedFrameworks(zp, package);
|
||||
var packaging = GetFiles(package).OrderBy(f => f.Path).ToArray();
|
||||
var packagingLib = GetLibFiles(package).OrderBy(f => f.Path).ToArray();
|
||||
|
||||
//for (int i = 0; i < zipf.Length; i++) {
|
||||
// if (zipf[i] != packagingLib[i])
|
||||
// throw new Exception();
|
||||
//}
|
||||
|
||||
Assert.Equal(packagingfw, zipfw);
|
||||
Assert.Equal(packaging, zipf);
|
||||
Assert.Equal(packagingLib, zipfLib);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ParsesNuspecCorrectly()
|
||||
{
|
||||
var inputPackage = IntegrationTestHelper.GetPath("fixtures", "FullNuspec.1.0.0.nupkg");
|
||||
var zp = new ZipPackage(inputPackage);
|
||||
|
||||
var dyn = ExposedObject.From(zp);
|
||||
|
||||
Assert.Equal("FullNuspec", zp.Id);
|
||||
Assert.Equal(SemanticVersion.Parse("1.0.0"), zp.Version);
|
||||
Assert.Equal(new[] { "Anaïs Betts", "Caelan Sayler" }, dyn.Authors);
|
||||
Assert.Equal(new Uri("https://github.com/clowd/Clowd.Squirrel"), zp.ProjectUrl);
|
||||
Assert.Equal(new Uri("https://user-images.githubusercontent.com/1287295/131249078-9e131e51-0b66-4dc7-8c0a-99cbea6bcf80.png"), zp.IconUrl);
|
||||
Assert.Equal("A test description", dyn.Description);
|
||||
Assert.Equal("A summary", dyn.Summary);
|
||||
Assert.Equal("release notes\nwith multiple lines", zp.ReleaseNotes);
|
||||
Assert.Equal("Copyright ©", dyn.Copyright);
|
||||
Assert.Equal("en-US", zp.Language);
|
||||
Assert.Equal("Squirrel for Windows", dyn.Title);
|
||||
|
||||
Assert.NotEmpty(zp.DependencySets);
|
||||
var net461 = zp.DependencySets.First();
|
||||
Assert.Equal(new[] { ".NETFramework4.6.1" }, net461.SupportedFrameworks);
|
||||
Assert.Equal(".NETFramework4.6.1", net461.TargetFramework);
|
||||
|
||||
Assert.NotEmpty(net461.Dependencies);
|
||||
var dvt = net461.Dependencies.First();
|
||||
Assert.Equal("System.ValueTuple", dvt.Id);
|
||||
Assert.Equal("4.5.0", dvt.VersionSpec);
|
||||
|
||||
Assert.Equal(new[] { "net5.0" }, zp.DependencySets.Last().SupportedFrameworks);
|
||||
|
||||
Assert.NotEmpty(zp.FrameworkAssemblies);
|
||||
var fw = zp.FrameworkAssemblies.First();
|
||||
Assert.Equal("System.Net.Http", fw.AssemblyName);
|
||||
Assert.Equal(new[] { ".NETFramework4.6.1" }, fw.SupportedFrameworks);
|
||||
}
|
||||
|
||||
IEnumerable<string> GetSupportedFrameworks(ZipPackage zp, Package package)
|
||||
{
|
||||
var fileFrameworks = from part in package.GetParts()
|
||||
where IsPackageFile(part)
|
||||
select NugetUtil.ParseFrameworkNameFromFilePath(NugetUtil.GetPath(part.Uri), out var effectivePath);
|
||||
|
||||
return zp.FrameworkAssemblies.SelectMany(f => f.SupportedFrameworks)
|
||||
.Concat(fileFrameworks)
|
||||
.Where(f => f != null)
|
||||
.Distinct();
|
||||
}
|
||||
|
||||
IEnumerable<IPackageFile> GetLibFiles(Package package)
|
||||
{
|
||||
return GetFiles(package, NugetUtil.LibDirectory);
|
||||
}
|
||||
|
||||
IEnumerable<IPackageFile> GetFiles(Package package, string directory)
|
||||
{
|
||||
string folderPrefix = directory + Path.DirectorySeparatorChar;
|
||||
return GetFiles(package).Where(file => file.Path.StartsWith(folderPrefix, StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
|
||||
List<IPackageFile> GetFiles(Package package)
|
||||
{
|
||||
return (from part in package.GetParts()
|
||||
where IsPackageFile(part)
|
||||
select (IPackageFile) new ZipPackageFile(part.Uri)).ToList();
|
||||
}
|
||||
|
||||
bool IsPackageFile(PackagePart part)
|
||||
{
|
||||
string path = NugetUtil.GetPath(part.Uri);
|
||||
string directory = Path.GetDirectoryName(path);
|
||||
string[] ExcludePaths = new[] { "_rels", "package" };
|
||||
return !ExcludePaths.Any(p => directory.StartsWith(p, StringComparison.OrdinalIgnoreCase)) && !IsManifest(path);
|
||||
}
|
||||
|
||||
bool IsManifest(string p)
|
||||
{
|
||||
return Path.GetExtension(p).Equals(NugetUtil.ManifestExtension, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
test/Squirrel.Tests/fixtures/Caliburn.Micro.1.4.1.nupkg
Normal file
BIN
test/Squirrel.Tests/fixtures/Caliburn.Micro.1.4.1.nupkg
Normal file
Binary file not shown.
BIN
test/Squirrel.Tests/fixtures/Caliburn.Micro.1.5.2.nupkg
Normal file
BIN
test/Squirrel.Tests/fixtures/Caliburn.Micro.1.5.2.nupkg
Normal file
Binary file not shown.
BIN
test/Squirrel.Tests/fixtures/CaliburnMicroDemo.1.0.0.nupkg
Normal file
BIN
test/Squirrel.Tests/fixtures/CaliburnMicroDemo.1.0.0.nupkg
Normal file
Binary file not shown.
BIN
test/Squirrel.Tests/fixtures/Clowd-3.4.287-full.nupkg
Normal file
BIN
test/Squirrel.Tests/fixtures/Clowd-3.4.287-full.nupkg
Normal file
Binary file not shown.
BIN
test/Squirrel.Tests/fixtures/Clowd-3.4.288-delta.nupkg
Normal file
BIN
test/Squirrel.Tests/fixtures/Clowd-3.4.288-delta.nupkg
Normal file
Binary file not shown.
BIN
test/Squirrel.Tests/fixtures/Clowd-3.4.291-delta.nupkg
Normal file
BIN
test/Squirrel.Tests/fixtures/Clowd-3.4.291-delta.nupkg
Normal file
Binary file not shown.
BIN
test/Squirrel.Tests/fixtures/Clowd-3.4.292-delta.nupkg
Normal file
BIN
test/Squirrel.Tests/fixtures/Clowd-3.4.292-delta.nupkg
Normal file
Binary file not shown.
BIN
test/Squirrel.Tests/fixtures/FullNuspec.1.0.0.nupkg
Normal file
BIN
test/Squirrel.Tests/fixtures/FullNuspec.1.0.0.nupkg
Normal file
Binary file not shown.
36
test/Squirrel.Tests/fixtures/FullNuspec.nuspec
Normal file
36
test/Squirrel.Tests/fixtures/FullNuspec.nuspec
Normal file
@@ -0,0 +1,36 @@
|
||||
<?xml version="1.0"?>
|
||||
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>FullNuspec</id>
|
||||
<version>1.0</version>
|
||||
<authors>Anaïs Betts, Caelan Sayler</authors>
|
||||
<projectUrl>https://github.com/clowd/Clowd.Squirrel</projectUrl>
|
||||
<iconUrl>https://user-images.githubusercontent.com/1287295/131249078-9e131e51-0b66-4dc7-8c0a-99cbea6bcf80.png</iconUrl>
|
||||
<description>A test description</description>
|
||||
<summary>A summary</summary>
|
||||
<releaseNotes>
|
||||
release notes
|
||||
with multiple lines
|
||||
</releaseNotes>
|
||||
<copyright>Copyright ©</copyright>
|
||||
<language>en-US</language>
|
||||
<title>Squirrel for Windows</title>
|
||||
|
||||
<dependencies>
|
||||
<group targetFramework=".NETFramework4.6.1">
|
||||
<dependency id="System.ValueTuple" version="4.5.0" exclude="Build,Analyzers" />
|
||||
</group>
|
||||
<group targetFramework="net5.0">
|
||||
<dependency id="System.IO.Packaging" version="5.0.0" exclude="Build,Analyzers" />
|
||||
</group>
|
||||
</dependencies>
|
||||
<frameworkAssemblies>
|
||||
<frameworkAssembly assemblyName="System.Net.Http" targetFramework=".NETFramework4.6.1" />
|
||||
<frameworkAssembly assemblyName="System.Web" targetFramework=".NETFramework4.6.1" />
|
||||
</frameworkAssemblies>
|
||||
|
||||
</metadata>
|
||||
<files>
|
||||
<file src="FullNuspec.txt" target="tools" />
|
||||
</files>
|
||||
</package>
|
||||
1
test/Squirrel.Tests/fixtures/FullNuspec.txt
Normal file
1
test/Squirrel.Tests/fixtures/FullNuspec.txt
Normal file
@@ -0,0 +1 @@
|
||||
asd
|
||||
BIN
test/Squirrel.Tests/fixtures/NotSquirrelAwareApp.exe
Normal file
BIN
test/Squirrel.Tests/fixtures/NotSquirrelAwareApp.exe
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
test/Squirrel.Tests/fixtures/PublishSingleFileAwareApp.exe
Normal file
BIN
test/Squirrel.Tests/fixtures/PublishSingleFileAwareApp.exe
Normal file
Binary file not shown.
1
test/Squirrel.Tests/fixtures/RELEASES-OnePointOh
Normal file
1
test/Squirrel.Tests/fixtures/RELEASES-OnePointOh
Normal file
@@ -0,0 +1 @@
|
||||
94689fede03fed7ab59c24337673a27837f0c3ec MyCoolApp-1.0.nupkg 1004502
|
||||
3
test/Squirrel.Tests/fixtures/RELEASES-OnePointOne
Normal file
3
test/Squirrel.Tests/fixtures/RELEASES-OnePointOne
Normal file
@@ -0,0 +1,3 @@
|
||||
94689fede03fed7ab59c24337673a27837f0c3ec MyCoolApp-1.0.nupkg 1004502
|
||||
3a2eadd15dd984e4559f2b4d790ec8badaeb6a39 MyCoolApp-1.1.nupkg 1040561
|
||||
14db31d2647c6d2284882a2e101924a9c409ee67 MyCoolApp-1.1-delta.nupkg 80396
|
||||
BIN
test/Squirrel.Tests/fixtures/Setup.exe
Normal file
BIN
test/Squirrel.Tests/fixtures/Setup.exe
Normal file
Binary file not shown.
BIN
test/Squirrel.Tests/fixtures/SpecialCharacters-0.1.0-full.nupkg
Normal file
BIN
test/Squirrel.Tests/fixtures/SpecialCharacters-0.1.0-full.nupkg
Normal file
Binary file not shown.
BIN
test/Squirrel.Tests/fixtures/Squirrel.Core.1.0.0.0-full.nupkg
Normal file
BIN
test/Squirrel.Tests/fixtures/Squirrel.Core.1.0.0.0-full.nupkg
Normal file
Binary file not shown.
BIN
test/Squirrel.Tests/fixtures/Squirrel.Core.1.0.0.0.nupkg
Normal file
BIN
test/Squirrel.Tests/fixtures/Squirrel.Core.1.0.0.0.nupkg
Normal file
Binary file not shown.
BIN
test/Squirrel.Tests/fixtures/Squirrel.Core.1.1.0.0-delta.nupkg
Normal file
BIN
test/Squirrel.Tests/fixtures/Squirrel.Core.1.1.0.0-delta.nupkg
Normal file
Binary file not shown.
BIN
test/Squirrel.Tests/fixtures/Squirrel.Core.1.1.0.0-full.nupkg
Normal file
BIN
test/Squirrel.Tests/fixtures/Squirrel.Core.1.1.0.0-full.nupkg
Normal file
Binary file not shown.
BIN
test/Squirrel.Tests/fixtures/Squirrel.Core.1.1.0.0.nupkg
Normal file
BIN
test/Squirrel.Tests/fixtures/Squirrel.Core.1.1.0.0.nupkg
Normal file
Binary file not shown.
29
test/Squirrel.Tests/fixtures/Squirrel.Core.1.1.0.0.nuspec
Normal file
29
test/Squirrel.Tests/fixtures/Squirrel.Core.1.1.0.0.nuspec
Normal file
@@ -0,0 +1,29 @@
|
||||
<?xml version="1.0"?>
|
||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata>
|
||||
<version>1.1.0.0</version>
|
||||
<authors>Administrator</authors>
|
||||
<owners>Administrator</owners>
|
||||
<dependencies>
|
||||
<dependency id="DotNetZip" version="1.9.1.8" />
|
||||
<dependency id="Ix_Experimental-Main" version="1.1.10823" />
|
||||
<dependency id="NLog" version="2.0.0.2000" />
|
||||
<dependency id="reactiveui-core" version="2.5.2.0" />
|
||||
</dependencies>
|
||||
<id>NSync.Core</id>
|
||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||
<description>Description</description>
|
||||
<releaseNotes>
|
||||
## Release Notes for 1.1
|
||||
|
||||
1. Did some cool stuff
|
||||
1. Did another thing
|
||||
1. Did a third thing, pretty crazy!
|
||||
|
||||
Make *sure* to refrobulate the confabulator or **terrible things will happen!**
|
||||
</releaseNotes>
|
||||
</metadata>
|
||||
<files>
|
||||
<file src="lib\net40\NSync.Core.dll" target="lib\net40\NSync.Core.dll" />
|
||||
</files>
|
||||
</package>
|
||||
BIN
test/Squirrel.Tests/fixtures/Squirrel.Core.1.2.0.0-full.nupkg
Normal file
BIN
test/Squirrel.Tests/fixtures/Squirrel.Core.1.2.0.0-full.nupkg
Normal file
Binary file not shown.
BIN
test/Squirrel.Tests/fixtures/Squirrel.Core.1.3.0.0-full.nupkg
Normal file
BIN
test/Squirrel.Tests/fixtures/Squirrel.Core.1.3.0.0-full.nupkg
Normal file
Binary file not shown.
Binary file not shown.
BIN
test/Squirrel.Tests/fixtures/Squirrel.Tests.0.1.0-pre.nupkg
Normal file
BIN
test/Squirrel.Tests/fixtures/Squirrel.Tests.0.1.0-pre.nupkg
Normal file
Binary file not shown.
BIN
test/Squirrel.Tests/fixtures/Squirrel.Tests.0.2.0-pre.nupkg
Normal file
BIN
test/Squirrel.Tests/fixtures/Squirrel.Tests.0.2.0-pre.nupkg
Normal file
Binary file not shown.
BIN
test/Squirrel.Tests/fixtures/SquirrelAwareTweakedNetCoreApp.exe
Normal file
BIN
test/Squirrel.Tests/fixtures/SquirrelAwareTweakedNetCoreApp.exe
Normal file
Binary file not shown.
14
test/Squirrel.Tests/fixtures/SquirrelInstalledApp.nuspec
Normal file
14
test/Squirrel.Tests/fixtures/SquirrelInstalledApp.nuspec
Normal file
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>SquirrelInstalledApp</id>
|
||||
<version>0.1.0</version>
|
||||
<authors>Anaïs Betts</authors>
|
||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||
<description>My package description.</description>
|
||||
</metadata>
|
||||
<files>
|
||||
<file src="NotSquirrelAwareApp.exe" target="lib\net45\NotSquirrelAwareApp.exe" />
|
||||
<file src="SquirrelAwareApp.exe" target="lib\net45\SquirrelAwareApp.exe" />
|
||||
</files>
|
||||
</package>
|
||||
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>Squirrel.Installed.App</id>
|
||||
<version>0.1.0</version>
|
||||
<authors>Anaïs Betts</authors>
|
||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||
<description>My package description.</description>
|
||||
</metadata>
|
||||
<files>
|
||||
<file src="NotSquirrelAwareApp.exe" target="lib\net45\NotSquirrelAwareApp.exe" />
|
||||
<file src="SquirrelAwareApp.exe" target="lib\net45\SquirrelAwareApp.exe" />
|
||||
</files>
|
||||
</package>
|
||||
BIN
test/Squirrel.Tests/fixtures/ThisShouldBeANet45Project.1.0.nupkg
Normal file
BIN
test/Squirrel.Tests/fixtures/ThisShouldBeANet45Project.1.0.nupkg
Normal file
Binary file not shown.
BIN
test/Squirrel.Tests/fixtures/atom.exe
Normal file
BIN
test/Squirrel.Tests/fixtures/atom.exe
Normal file
Binary file not shown.
12
test/Squirrel.Tests/fixtures/content-types/basic-merged.xml
Normal file
12
test/Squirrel.Tests/fixtures/content-types/basic-merged.xml
Normal file
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">
|
||||
<Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml" />
|
||||
<Default Extension="nuspec" ContentType="application/octet" />
|
||||
<Default Extension="exe" ContentType="application/octet" />
|
||||
<Default Extension="psmdcp" ContentType="application/vnd.openxmlformats-package.core-properties+xml" />
|
||||
<Default Extension="diff" ContentType="application/octet" />
|
||||
<Default Extension="bsdiff" ContentType="application/octet" />
|
||||
<Default Extension="dll" ContentType="application/octet" />
|
||||
<Default Extension="ico" ContentType="application/octet" />
|
||||
<Default Extension="shasum" ContentType="text/plain" />
|
||||
</Types>
|
||||
7
test/Squirrel.Tests/fixtures/content-types/basic.xml
Normal file
7
test/Squirrel.Tests/fixtures/content-types/basic.xml
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">
|
||||
<Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml" />
|
||||
<Default Extension="nuspec" ContentType="application/octet" />
|
||||
<Default Extension="exe" ContentType="application/octet" />
|
||||
<Default Extension="psmdcp" ContentType="application/vnd.openxmlformats-package.core-properties+xml" />
|
||||
</Types>
|
||||
@@ -0,0 +1,65 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">
|
||||
<Default ContentType="application/vnd.openxmlformats-package.relationships+xml" Extension="rels"/>
|
||||
<Default ContentType="application/octet" Extension="nuspec"/>
|
||||
<Default ContentType="application/octet" Extension="html"/>
|
||||
<Default ContentType="application/octet" Extension="nsi"/>
|
||||
<Default ContentType="application/octet" Extension="css"/>
|
||||
<Default ContentType="application/octet" Extension="otf"/>
|
||||
<Default ContentType="application/octet" Extension="png"/>
|
||||
<Default ContentType="application/octet" Extension="js"/>
|
||||
<Default ContentType="application/octet" Extension="json"/>
|
||||
<Default ContentType="application/octet" Extension="md"/>
|
||||
<Default ContentType="application/octet" Extension="yml"/>
|
||||
<Default ContentType="application/octet" Extension="eot"/>
|
||||
<Default ContentType="application/octet" Extension="svg"/>
|
||||
<Default ContentType="application/octet" Extension="ttf"/>
|
||||
<Default ContentType="application/octet" Extension="woff"/>
|
||||
<Default ContentType="application/octet" Extension="jpg"/>
|
||||
<Default ContentType="application/octet" Extension="less"/>
|
||||
<Default ContentType="application/octet" Extension="coffee"/>
|
||||
<Default ContentType="application/octet" Extension="map"/>
|
||||
<Default ContentType="application/octet" Extension="txt"/>
|
||||
<Default ContentType="application/octet" Extension="gif"/>
|
||||
<Default ContentType="application/octet" Extension="markdown"/>
|
||||
<Default ContentType="application/octet" Extension="jade"/>
|
||||
<Default ContentType="application/octet" Extension="sh"/>
|
||||
<Default ContentType="application/octet" Extension="text"/>
|
||||
<Default ContentType="application/octet" Extension="pl"/>
|
||||
<Default ContentType="application/octet" Extension="dphpd"/>
|
||||
<Default ContentType="application/octet" Extension="php"/>
|
||||
<Default ContentType="application/octet" Extension="refine"/>
|
||||
<Default ContentType="application/octet" Extension="wav"/>
|
||||
<Default ContentType="application/octet" Extension="mdown"/>
|
||||
<Default ContentType="application/octet" Extension="bar"/>
|
||||
<Default ContentType="application/octet" Extension="template"/>
|
||||
<Default ContentType="application/octet" Extension="ico"/>
|
||||
<Default ContentType="application/octet" Extension="dll"/>
|
||||
<Default ContentType="application/octet" Extension="pak"/>
|
||||
<Default ContentType="application/octet" Extension="exe"/>
|
||||
<Default ContentType="application/octet" Extension="diff"/>
|
||||
<Default ContentType="application/octet" Extension="bsdiff"/>
|
||||
<Default ContentType="text/plain" Extension="shasum"/>
|
||||
<Default ContentType="application/vnd.openxmlformats-package.core-properties+xml" Extension="psmdcp"/>
|
||||
<Override ContentType="application/octet" PartName="/Content/frontend/js/library/bootstrap/CNAME"/>
|
||||
<Override ContentType="application/octet" PartName="/Content/frontend/js/library/bootstrap/LICENSE"/>
|
||||
<Override ContentType="application/octet" PartName="/Content/frontend/js/library/hammerjs/LICENSE"/>
|
||||
<Override ContentType="application/octet" PartName="/Content/frontend/js/library/iscroll/LICENSE"/>
|
||||
<Override ContentType="application/octet" PartName="/Content/frontend/js/library/jqBootstrapValidation/LICENSE"/>
|
||||
<Override ContentType="application/octet" PartName="/Content/frontend/js/library/jquery-ui/MANIFEST"/>
|
||||
<Override ContentType="application/octet" PartName="/Content/frontend/js/library/page/Makefile"/>
|
||||
<Override ContentType="application/octet" PartName="/Content/frontend/js/library/requirejs/LICENSE"/>
|
||||
<Override ContentType="application/octet" PartName="/Content/frontend/js/library/requirejs/tests/bar"/>
|
||||
<Override ContentType="application/octet" PartName="/Content/frontend/js/library/requirejs/tests/foo"/>
|
||||
<Override ContentType="application/octet" PartName="/Content/frontend/js/library/requirejs/tests/doh/LICENSE"/>
|
||||
<Override ContentType="application/octet" PartName="/Content/frontend/js/library/requirejs/tests/doh/README"/>
|
||||
<Override ContentType="application/octet" PartName="/Content/frontend/js/library/requirejs/tests/doh/_sounds/LICENSE"/>
|
||||
<Override ContentType="application/octet" PartName="/Content/frontend/js/library/requirejs/tests/toUrl/sub/noext"/>
|
||||
<Override ContentType="application/octet" PartName="/Content/frontend/js/library/requirejs-domready/LICENSE"/>
|
||||
<Override ContentType="application/octet" PartName="/Content/frontend/js/library/requirejs-plugins/examples/js/foo"/>
|
||||
<Override ContentType="application/octet" PartName="/Content/frontend/js/library/requirejs-text/LICENSE"/>
|
||||
<Override ContentType="application/octet" PartName="/Content/frontend/js/library/select2/LICENSE"/>
|
||||
<Override ContentType="application/octet" PartName="/Content/frontend/js/library/underscore/CNAME"/>
|
||||
<Override ContentType="application/octet" PartName="/Content/frontend/js/library/underscore/LICENSE"/>
|
||||
<Override ContentType="application/octet" PartName="/Content/frontend/js/library/underscore/Rakefile"/>
|
||||
</Types>
|
||||
62
test/Squirrel.Tests/fixtures/content-types/complex.xml
Normal file
62
test/Squirrel.Tests/fixtures/content-types/complex.xml
Normal file
@@ -0,0 +1,62 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">
|
||||
<Default ContentType="application/vnd.openxmlformats-package.relationships+xml" Extension="rels"/>
|
||||
<Default ContentType="application/octet" Extension="nuspec"/>
|
||||
<Default ContentType="application/octet" Extension="html"/>
|
||||
<Default ContentType="application/octet" Extension="nsi"/>
|
||||
<Default ContentType="application/octet" Extension="css"/>
|
||||
<Default ContentType="application/octet" Extension="otf"/>
|
||||
<Default ContentType="application/octet" Extension="png"/>
|
||||
<Default ContentType="application/octet" Extension="js"/>
|
||||
<Default ContentType="application/octet" Extension="json"/>
|
||||
<Default ContentType="application/octet" Extension="md"/>
|
||||
<Default ContentType="application/octet" Extension="yml"/>
|
||||
<Default ContentType="application/octet" Extension="eot"/>
|
||||
<Default ContentType="application/octet" Extension="svg"/>
|
||||
<Default ContentType="application/octet" Extension="ttf"/>
|
||||
<Default ContentType="application/octet" Extension="woff"/>
|
||||
<Default ContentType="application/octet" Extension="jpg"/>
|
||||
<Default ContentType="application/octet" Extension="less"/>
|
||||
<Default ContentType="application/octet" Extension="coffee"/>
|
||||
<Default ContentType="application/octet" Extension="map"/>
|
||||
<Default ContentType="application/octet" Extension="txt"/>
|
||||
<Default ContentType="application/octet" Extension="gif"/>
|
||||
<Default ContentType="application/octet" Extension="markdown"/>
|
||||
<Default ContentType="application/octet" Extension="jade"/>
|
||||
<Default ContentType="application/octet" Extension="sh"/>
|
||||
<Default ContentType="application/octet" Extension="text"/>
|
||||
<Default ContentType="application/octet" Extension="pl"/>
|
||||
<Default ContentType="application/octet" Extension="dphpd"/>
|
||||
<Default ContentType="application/octet" Extension="php"/>
|
||||
<Default ContentType="application/octet" Extension="refine"/>
|
||||
<Default ContentType="application/octet" Extension="wav"/>
|
||||
<Default ContentType="application/octet" Extension="mdown"/>
|
||||
<Default ContentType="application/octet" Extension="bar"/>
|
||||
<Default ContentType="application/octet" Extension="template"/>
|
||||
<Default ContentType="application/octet" Extension="ico"/>
|
||||
<Default ContentType="application/octet" Extension="dll"/>
|
||||
<Default ContentType="application/octet" Extension="pak"/>
|
||||
<Default ContentType="application/octet" Extension="exe"/>
|
||||
<Default ContentType="application/vnd.openxmlformats-package.core-properties+xml" Extension="psmdcp"/>
|
||||
<Override ContentType="application/octet" PartName="/Content/frontend/js/library/bootstrap/CNAME"/>
|
||||
<Override ContentType="application/octet" PartName="/Content/frontend/js/library/bootstrap/LICENSE"/>
|
||||
<Override ContentType="application/octet" PartName="/Content/frontend/js/library/hammerjs/LICENSE"/>
|
||||
<Override ContentType="application/octet" PartName="/Content/frontend/js/library/iscroll/LICENSE"/>
|
||||
<Override ContentType="application/octet" PartName="/Content/frontend/js/library/jqBootstrapValidation/LICENSE"/>
|
||||
<Override ContentType="application/octet" PartName="/Content/frontend/js/library/jquery-ui/MANIFEST"/>
|
||||
<Override ContentType="application/octet" PartName="/Content/frontend/js/library/page/Makefile"/>
|
||||
<Override ContentType="application/octet" PartName="/Content/frontend/js/library/requirejs/LICENSE"/>
|
||||
<Override ContentType="application/octet" PartName="/Content/frontend/js/library/requirejs/tests/bar"/>
|
||||
<Override ContentType="application/octet" PartName="/Content/frontend/js/library/requirejs/tests/foo"/>
|
||||
<Override ContentType="application/octet" PartName="/Content/frontend/js/library/requirejs/tests/doh/LICENSE"/>
|
||||
<Override ContentType="application/octet" PartName="/Content/frontend/js/library/requirejs/tests/doh/README"/>
|
||||
<Override ContentType="application/octet" PartName="/Content/frontend/js/library/requirejs/tests/doh/_sounds/LICENSE"/>
|
||||
<Override ContentType="application/octet" PartName="/Content/frontend/js/library/requirejs/tests/toUrl/sub/noext"/>
|
||||
<Override ContentType="application/octet" PartName="/Content/frontend/js/library/requirejs-domready/LICENSE"/>
|
||||
<Override ContentType="application/octet" PartName="/Content/frontend/js/library/requirejs-plugins/examples/js/foo"/>
|
||||
<Override ContentType="application/octet" PartName="/Content/frontend/js/library/requirejs-text/LICENSE"/>
|
||||
<Override ContentType="application/octet" PartName="/Content/frontend/js/library/select2/LICENSE"/>
|
||||
<Override ContentType="application/octet" PartName="/Content/frontend/js/library/underscore/CNAME"/>
|
||||
<Override ContentType="application/octet" PartName="/Content/frontend/js/library/underscore/LICENSE"/>
|
||||
<Override ContentType="application/octet" PartName="/Content/frontend/js/library/underscore/Rakefile"/>
|
||||
</Types>
|
||||
@@ -0,0 +1,57 @@
|
||||
Apache License, Version 2.0
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
|
||||
|
||||
1. You must give any other recipients of the Work or Derivative Works a copy of this License; and
|
||||
|
||||
2. You must cause any modified files to carry prominent notices stating that You changed the files; and
|
||||
|
||||
3. You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
|
||||
|
||||
4. If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
71
test/Squirrel.Tests/fixtures/packages/Castle.Core.3.2.0/BreakingChanges.txt
vendored
Normal file
71
test/Squirrel.Tests/fixtures/packages/Castle.Core.3.2.0/BreakingChanges.txt
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
=== version 3.0
|
||||
================================================================================================
|
||||
change - Removed overloads of logging methods that were taking format string from ILogger and
|
||||
ILogger and IExtendedLogger and didn't have word Format in their name.
|
||||
For example:
|
||||
void Error(string format, params object[] args); // was removed
|
||||
void ErrorFormat(string format, params object[] args); //use this one instead
|
||||
|
||||
|
||||
impact - low
|
||||
fixability - medium
|
||||
revision -
|
||||
|
||||
description - To minimize confusion and duplication those methods were removed.
|
||||
|
||||
fix - Use methods that have explicit "Format" word in their name and same signature.
|
||||
================================================================================================
|
||||
change - Removed WebLogger and WebLoggerFactory
|
||||
|
||||
impact - low
|
||||
fixability - medium
|
||||
revision -
|
||||
|
||||
description - To minimize management overhead the classes were removed so that only single
|
||||
Client Profile version of Castle.Core can be distributed.
|
||||
|
||||
fix - You can use NLog or Log4Net web logger integration, or reuse implementation of existing
|
||||
web logger and use it as a custom logger.
|
||||
|
||||
================================================================================================
|
||||
change - Removed obsolete overload of ProxyGenerator.CreateClassProxy
|
||||
|
||||
impact - low
|
||||
fixability - trivial
|
||||
revision -
|
||||
|
||||
description - Deprecated overload of ProxyGenerator.CreateClassProxy was removed to keep the
|
||||
method consistent with other methods and to remove confusion
|
||||
|
||||
fix - whenever removed overload was used, use one of the other overloads.
|
||||
|
||||
================================================================================================
|
||||
change - IProxyGenerationHook.NonVirtualMemberNotification method was renamed
|
||||
|
||||
impact - high
|
||||
fixability - easy
|
||||
revision -
|
||||
|
||||
description - to accommodate class proxies with target method NonVirtualMemberNotification on
|
||||
IProxyGenerationHook type was renamed to more accurate NonProxyableMemberNotification
|
||||
since for class proxies with target not just methods but also fields and other member that
|
||||
break the abstraction will be passed to this method.
|
||||
|
||||
fix - whenever NonVirtualMemberNotification is used/implemented change the method name to
|
||||
NonProxyableMemberNotification. Implementors should also accommodate possibility that not
|
||||
only MethodInfos will be passed as method's second parameter.
|
||||
|
||||
================================================================================================
|
||||
change - DynamicProxy will now allow to intercept members of System.Object
|
||||
|
||||
impact - very low
|
||||
fixability - easy
|
||||
revision -
|
||||
|
||||
description - to allow scenarios like mocking of System.Object members, DynamicProxy will not
|
||||
disallow proxying of these methods anymore. AllMethodsHook (default IProxyGenerationHook)
|
||||
will still filter them out though.
|
||||
|
||||
fix - whenever custom IProxyGenerationHook is used, user should account for System.Object's
|
||||
members being now passed to ShouldInterceptMethod and NonVirtualMemberNotification methods
|
||||
and if neccessary update the code to handle them appropriately.
|
||||
BIN
test/Squirrel.Tests/fixtures/packages/Castle.Core.3.2.0/Castle.Core.3.2.0.nupkg
vendored
Normal file
BIN
test/Squirrel.Tests/fixtures/packages/Castle.Core.3.2.0/Castle.Core.3.2.0.nupkg
vendored
Normal file
Binary file not shown.
196
test/Squirrel.Tests/fixtures/packages/Castle.Core.3.2.0/Changes.txt
vendored
Normal file
196
test/Squirrel.Tests/fixtures/packages/Castle.Core.3.2.0/Changes.txt
vendored
Normal file
@@ -0,0 +1,196 @@
|
||||
3.2.0 (2013-02-16)
|
||||
==================
|
||||
- fixed DYNPROXY-179 - Exception when creating a generic proxy (from cache)
|
||||
- fixed DYNPROXY-175 - invalid CompositionInvocation type used when code uses interface proxies with and without InterceptorSelector
|
||||
|
||||
3.1.0 (2012-08-05)
|
||||
==================
|
||||
- fixed DYNPROXY-174 - Unable to cast object of type 'System.Collections.ObjectModel.ReadOnlyCollection`1[System.Reflection.CustomAttributeTypedArgument]' to type 'System.Array'
|
||||
|
||||
3.1.0 RC (2012-07-08)
|
||||
==================
|
||||
- support multiple inheritance of DA attributes on interfaces.
|
||||
- BREAKING CHANGE: removed propogate child notifications as it violated INotifyPropertyChanged contract
|
||||
- improved DictionaryAdapter performance
|
||||
- generalized IBindingList support for DictionaryAdapters
|
||||
- added reference support to XmlAdapter
|
||||
- BRAKING CHANGE: refactored XPathAdapter into XmlAdapter with much more flexibility to support other input like XLinq
|
||||
|
||||
- implemented CORE-43 - Add option to skip configuring log4net/nlog
|
||||
|
||||
- fixed CORE-44 - NLog logger does not preserver call site info
|
||||
- fixed DYNPROXY-171 - PEVerify error on generic method definition
|
||||
- fixed DYNPROXY-170 - Calls to properties inside non-intercepted methods are not forwarded to target object (regression from v2.5)
|
||||
- fixed DYNPROXY-169 - Support IChangeProxyTarget on additional interfaces and mixins when using CreateInterfaceProxyWithTargetInterface
|
||||
|
||||
3.0.0 (2011-12-13)
|
||||
==================
|
||||
no major changes since RC
|
||||
|
||||
3.0.0 RC 1 (2011-11-20)
|
||||
==================
|
||||
- Applied Jeff Sharps patch that refactored Xml DictionaryAdapter to improve maintainability and enable more complete functionality
|
||||
|
||||
- fixed DYNPROXY-165 - Object.GetType() and Object.MemberwiseClone() should be ignored and not reported as non-interceptable to IProxyGenerationHook
|
||||
- fixed DYNPROXY-164 - Invalid Proxy type generated when there are more than one base class generic constraints
|
||||
- fixed DYNPROXY-162 - ref or out parameters can not be passed back if proxied method throw an exception
|
||||
|
||||
3.0.0 beta 1 (2011-08-14)
|
||||
==================
|
||||
- fixed CORE-37 - TAB characters in the XML Configuration of a component parameter is read as String.Empty
|
||||
- fixed DYNPROXY-161 - Strong Named DynamicProxy Assembly Not Available in Silverligh
|
||||
- fixed DYNPROXY-159 - Sorting MemberInfo array for serialization has side effects
|
||||
- fixed DYNPROXY-158 - Can't create class proxy with target and without target in same ProxyGenerator
|
||||
- fixed DYNPROXY-153 - When proxying a generic interface which has an interface as GenericType . No proxy can be created
|
||||
- fixed DYNPROXY-151 - Cast error when using attributes
|
||||
|
||||
- implemented CORE-33 - Add lazy logging
|
||||
- implemented DYNPROXY-156 - Provide mechanism for interceptors to implement retry logic
|
||||
|
||||
- removed obsolete members from ILogger and its implementations
|
||||
|
||||
2.5.2 (2010-11-15)
|
||||
==================
|
||||
- fixed DYNPROXY-150 - Finalizer should not be proxied
|
||||
- implemented DYNPROXY-149 - Make AllMethodsHook members virtual so it can be used as a base class
|
||||
- fixed DYNPROXY-147 - Can't crete class proxies with two non-public methods having same argument types but different return type
|
||||
- fixed DYNPROXY-145 Unable to proxy System.Threading.SynchronizationContext (.NET 4.0)
|
||||
- fixed DYNPROXY-144 - params argument not supported in constructor
|
||||
- fixed DYNPROXY-143 - Permit call to reach "non-proxied" methods of inherited interfaces
|
||||
- implemented DYNPROXY-139 - Better error message
|
||||
- fixed DYNPROXY-133 - Debug assertion in ClassProxyInstanceContributor fails when proxying ISerializable with an explicit implementation of GetObjectData
|
||||
- fixed CORE-32 - Determining if permission is granted via PermissionUtil does not work in .NET 4
|
||||
- applied patch by Alwin Meijs - ExtendedLog4netFactory can be configured with a stream from for example an embedded log4net xml config
|
||||
- Upgraded NLog to 2.0 Beta 1
|
||||
- Added DefaultXmlSerializer to bridge XPathAdapter with standard Xml Serialization.
|
||||
- XPathAdapter for DictionaryAdapter added IXPathSerializer to provide hooks for custom serialization.
|
||||
|
||||
2.5.1 (2010-09-21)
|
||||
==================
|
||||
- Interface proxy with target Interface now accepts null as a valid target value (which can be replaced at a later stage).
|
||||
- DictionaryAdapter behavior overrides are now ordered with all other behaviors
|
||||
- BREAKING CHANGE: removed web logger so that by default Castle.Core works in .NET 4 client profile
|
||||
- added paramter to ModuleScope disabling usage of signed modules. This is to workaround issue DYNPROXY-134. Also a descriptive exception message is being thrown now when the issue is detected.
|
||||
- Added IDictionaryBehaviorBuilder to allow grouping behaviors
|
||||
- Added GenericDictionaryAdapter to simplify generic value sources
|
||||
- fixed issue DYNPROXY-138 - Error message missing space
|
||||
- fixed false positive where DynamicProxy would not let you proxy interface with target interface when target object was a COM object.
|
||||
- fixed ReflectionBasedDictionaryAdapter when using indexed properties
|
||||
|
||||
2.5.0 (2010-08-21)
|
||||
==================
|
||||
- DynamicProxy will now not replicate non-public attribute types
|
||||
- Applied patch from Kenneth Siewers M<>ller which adds parameterless constructor to DefaultSmtpSender implementation, to be able to configure the inner SmtpClient from the application configuration file (system.net.smtp).
|
||||
- added support for .NET 4 and Silverlight 4, updated solution to VisualStudio 2010
|
||||
- Removed obsolete overload of CreateClassProxy
|
||||
- Added class proxy with taget
|
||||
- Added ability to intercept explicitly implemented generic interface methods on class proxy.
|
||||
- DynamicProxy does not disallow intercepting members of System.Object anymore. AllMethodsHook will still filter them out though.
|
||||
- Added ability to intercept explicitly implemented interface members on class proxy. Does not support generic members.
|
||||
- Merged DynamicProxy into Core binary
|
||||
- fixed DYNPROXY-ISSUE-132 - "MetaProperty equals implementation incorrect"
|
||||
- Fixed bug in DiagnosticsLoggerTestCase, where when running as non-admin, the teardown will throw SecurityException (contributed by maxild)
|
||||
- Split IoC specific classes into Castle.Windsor project
|
||||
- Merged logging services solution
|
||||
- Merged DynamicProxy project
|
||||
|
||||
1.2.0 (2010-01-11)
|
||||
==================
|
||||
|
||||
- Added IEmailSender interface and its default implementation
|
||||
|
||||
1.2.0 beta (2009-12-04)
|
||||
==================
|
||||
|
||||
- BREAKING CHANGE - added ChangeProxyTarget method to IChangeProxyTarget interface
|
||||
- added docs to IChangeProxyTarget methods
|
||||
- Fixed DYNPROXY-ISSUE-108 - Obtaining replicated custom attributes on proxy may fail when property setter throws exception on default value
|
||||
- Moved custom attribute replication from CustomAttributeUtil to new interface - IAttributeDisassembler
|
||||
- Exposed IAttributeDisassembler via ProxyGenerationOptions, so that users can plug their implementation for some convoluted scenarios. (for Silverlight)
|
||||
- Moved IInterceptorSelector from Dynamic Proxy to Core (IOC-ISSUE-156)
|
||||
|
||||
1.1.0 (2009-05-04)
|
||||
==================
|
||||
|
||||
- Applied Eric Hauser's patch fixing CORE-ISSUE-22
|
||||
"Support for environment variables in resource URI"
|
||||
|
||||
- Applied Gauthier Segay's patch fixing CORE-ISSUE-20
|
||||
"Castle.Core.Tests won't build via nant because it use TraceContext without referencing System.Web.dll"
|
||||
|
||||
- Added simple interface to ComponentModel to make optional properties required.
|
||||
|
||||
- Applied Mark's -- <mwatts42@gmail.com> -- patch that changes
|
||||
the Core to support being compiled for Silverlight 2
|
||||
|
||||
- Applied Louis DeJardin's patch adding TraceLogger as a new logger implementation
|
||||
|
||||
- Applied Chris Bilson's patch fixing CORE-15
|
||||
"WebLogger Throws When Logging Outside of an HttpContext"
|
||||
|
||||
Release Candidate 3
|
||||
===================
|
||||
|
||||
- Added IServiceProviderEx which extends IServiceProvider
|
||||
|
||||
- Added Pair<T,S> class.
|
||||
|
||||
- Applied Bill Pierce's patch fixing CORE-9
|
||||
"Allow CastleComponent Attribute to Specify Lifestyle in Constructor"
|
||||
|
||||
- Added UseSingleInterfaceProxy to CompomentModel to control the proxying
|
||||
behavior while maintaining backward compatibility.
|
||||
Added the corresponding ComponentProxyBehaviorAttribute.
|
||||
|
||||
- Made NullLogger and IExtnededLogger
|
||||
|
||||
- Enabled a new format on ILogger interface, with 6 overloads for each method:
|
||||
Debug(string)
|
||||
Debug(string, Exception)
|
||||
Debug(string, params object[])
|
||||
DebugFormat(string, params object[])
|
||||
DebugFormat(Exception, string, params object[])
|
||||
DebugFormat(IFormatProvider, string, params object[])
|
||||
DebugFormat(IFormatProvider, Exception, string, params object[])
|
||||
|
||||
The "FatalError" overloads where marked as [Obsolete], replaced by "Fatal" and "FatalFormat".
|
||||
|
||||
0.0.1.0
|
||||
=======
|
||||
|
||||
- Included IProxyTargetAccessor
|
||||
|
||||
- Removed IMethodInterceptor and IMethodInvocation, that have been replaced
|
||||
by IInterceptor and IInvocation
|
||||
|
||||
- Added FindByPropertyInfo to PropertySetCollection
|
||||
|
||||
- Made the DependencyModel.IsOptional property writable
|
||||
|
||||
- Applied Curtis Schlak's patch fixing IOC-27
|
||||
"assembly resource format only works for resources where the assemblies name and default namespace are the same."
|
||||
|
||||
Quoting:
|
||||
|
||||
"I chose to preserve backwards compatibility by implementing the code in the
|
||||
reverse order as suggested by the reporter. Given the following URI for a resource:
|
||||
|
||||
assembly://my.cool.assembly/context/moo/file.xml
|
||||
|
||||
It will initially look for an embedded resource with the manifest name of
|
||||
"my.cool.assembly.context.moo.file.xml" in the loaded assembly my.cool.assembly.dll.
|
||||
If it does not find it, then it looks for the embedded resource with the manifest name
|
||||
of "context.moo.file.xml".
|
||||
|
||||
- IServiceEnabledComponent Introduced to be used across the project as
|
||||
a standard way to have access to common services, for example, logger factories
|
||||
|
||||
- Added missing log factories
|
||||
|
||||
- Refactor StreamLogger and DiagnosticLogger to be more consistent behavior-wise
|
||||
|
||||
- Refactored WebLogger to extend LevelFilteredLogger (removed duplication)
|
||||
|
||||
- Refactored LoggerLevel order
|
||||
|
||||
- Project started
|
||||
13
test/Squirrel.Tests/fixtures/packages/Castle.Core.3.2.0/License.txt
vendored
Normal file
13
test/Squirrel.Tests/fixtures/packages/Castle.Core.3.2.0/License.txt
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
Copyright 2004-2013 Castle Project - http://www.castleproject.org/
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
BIN
test/Squirrel.Tests/fixtures/packages/Castle.Core.3.2.0/lib/net35/Castle.Core.dll
vendored
Normal file
BIN
test/Squirrel.Tests/fixtures/packages/Castle.Core.3.2.0/lib/net35/Castle.Core.dll
vendored
Normal file
Binary file not shown.
4754
test/Squirrel.Tests/fixtures/packages/Castle.Core.3.2.0/lib/net35/Castle.Core.xml
vendored
Normal file
4754
test/Squirrel.Tests/fixtures/packages/Castle.Core.3.2.0/lib/net35/Castle.Core.xml
vendored
Normal file
File diff suppressed because it is too large
Load Diff
BIN
test/Squirrel.Tests/fixtures/packages/Castle.Core.3.2.0/lib/net40-client/Castle.Core.dll
vendored
Normal file
BIN
test/Squirrel.Tests/fixtures/packages/Castle.Core.3.2.0/lib/net40-client/Castle.Core.dll
vendored
Normal file
Binary file not shown.
4754
test/Squirrel.Tests/fixtures/packages/Castle.Core.3.2.0/lib/net40-client/Castle.Core.xml
vendored
Normal file
4754
test/Squirrel.Tests/fixtures/packages/Castle.Core.3.2.0/lib/net40-client/Castle.Core.xml
vendored
Normal file
File diff suppressed because it is too large
Load Diff
BIN
test/Squirrel.Tests/fixtures/packages/Castle.Core.3.2.0/lib/net45/Castle.Core.dll
vendored
Normal file
BIN
test/Squirrel.Tests/fixtures/packages/Castle.Core.3.2.0/lib/net45/Castle.Core.dll
vendored
Normal file
Binary file not shown.
4754
test/Squirrel.Tests/fixtures/packages/Castle.Core.3.2.0/lib/net45/Castle.Core.xml
vendored
Normal file
4754
test/Squirrel.Tests/fixtures/packages/Castle.Core.3.2.0/lib/net45/Castle.Core.xml
vendored
Normal file
File diff suppressed because it is too large
Load Diff
BIN
test/Squirrel.Tests/fixtures/packages/Castle.Core.3.2.0/lib/sl4/Castle.Core.dll
vendored
Normal file
BIN
test/Squirrel.Tests/fixtures/packages/Castle.Core.3.2.0/lib/sl4/Castle.Core.dll
vendored
Normal file
Binary file not shown.
4223
test/Squirrel.Tests/fixtures/packages/Castle.Core.3.2.0/lib/sl4/Castle.Core.xml
vendored
Normal file
4223
test/Squirrel.Tests/fixtures/packages/Castle.Core.3.2.0/lib/sl4/Castle.Core.xml
vendored
Normal file
File diff suppressed because it is too large
Load Diff
BIN
test/Squirrel.Tests/fixtures/packages/Castle.Core.3.2.0/lib/sl5/Castle.Core.dll
vendored
Normal file
BIN
test/Squirrel.Tests/fixtures/packages/Castle.Core.3.2.0/lib/sl5/Castle.Core.dll
vendored
Normal file
Binary file not shown.
4223
test/Squirrel.Tests/fixtures/packages/Castle.Core.3.2.0/lib/sl5/Castle.Core.xml
vendored
Normal file
4223
test/Squirrel.Tests/fixtures/packages/Castle.Core.3.2.0/lib/sl5/Castle.Core.xml
vendored
Normal file
File diff suppressed because it is too large
Load Diff
10
test/Squirrel.Tests/fixtures/packages/Castle.Core.3.2.0/readme.txt
vendored
Normal file
10
test/Squirrel.Tests/fixtures/packages/Castle.Core.3.2.0/readme.txt
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
Thanks for downloading this Castle package.
|
||||
You can find full list of changes in changes.txt
|
||||
|
||||
Documentation (work in progress, contributions appreciated):
|
||||
Dictionary Adapter - http://docs.castleproject.org/Tools.Castle-DictionaryAdapter.ashx
|
||||
DynamicProxy - http://docs.castleproject.org/Tools.DynamicProxy.ashx
|
||||
Discusssion group: - http://groups.google.com/group/castle-project-users
|
||||
StackOverflow tags: - castle-dynamicproxy, castle-dictionaryadapter, castle
|
||||
|
||||
Issue tracker: - http://issues.castleproject.org/dashboard
|
||||
BIN
test/Squirrel.Tests/fixtures/packages/Microsoft.Web.Xdt.2.1.1/Microsoft.Web.Xdt.2.1.1.nupkg
vendored
Normal file
BIN
test/Squirrel.Tests/fixtures/packages/Microsoft.Web.Xdt.2.1.1/Microsoft.Web.Xdt.2.1.1.nupkg
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
test/Squirrel.Tests/fixtures/packages/Newtonsoft.Json.6.0.3/Newtonsoft.Json.6.0.3.nupkg
vendored
Normal file
BIN
test/Squirrel.Tests/fixtures/packages/Newtonsoft.Json.6.0.3/Newtonsoft.Json.6.0.3.nupkg
vendored
Normal file
Binary file not shown.
BIN
test/Squirrel.Tests/fixtures/packages/Newtonsoft.Json.6.0.3/lib/net20/Newtonsoft.Json.dll
vendored
Normal file
BIN
test/Squirrel.Tests/fixtures/packages/Newtonsoft.Json.6.0.3/lib/net20/Newtonsoft.Json.dll
vendored
Normal file
Binary file not shown.
9038
test/Squirrel.Tests/fixtures/packages/Newtonsoft.Json.6.0.3/lib/net20/Newtonsoft.Json.xml
vendored
Normal file
9038
test/Squirrel.Tests/fixtures/packages/Newtonsoft.Json.6.0.3/lib/net20/Newtonsoft.Json.xml
vendored
Normal file
File diff suppressed because it is too large
Load Diff
BIN
test/Squirrel.Tests/fixtures/packages/Newtonsoft.Json.6.0.3/lib/net35/Newtonsoft.Json.dll
vendored
Normal file
BIN
test/Squirrel.Tests/fixtures/packages/Newtonsoft.Json.6.0.3/lib/net35/Newtonsoft.Json.dll
vendored
Normal file
Binary file not shown.
8181
test/Squirrel.Tests/fixtures/packages/Newtonsoft.Json.6.0.3/lib/net35/Newtonsoft.Json.xml
vendored
Normal file
8181
test/Squirrel.Tests/fixtures/packages/Newtonsoft.Json.6.0.3/lib/net35/Newtonsoft.Json.xml
vendored
Normal file
File diff suppressed because it is too large
Load Diff
BIN
test/Squirrel.Tests/fixtures/packages/Newtonsoft.Json.6.0.3/lib/net40/Newtonsoft.Json.dll
vendored
Normal file
BIN
test/Squirrel.Tests/fixtures/packages/Newtonsoft.Json.6.0.3/lib/net40/Newtonsoft.Json.dll
vendored
Normal file
Binary file not shown.
8488
test/Squirrel.Tests/fixtures/packages/Newtonsoft.Json.6.0.3/lib/net40/Newtonsoft.Json.xml
vendored
Normal file
8488
test/Squirrel.Tests/fixtures/packages/Newtonsoft.Json.6.0.3/lib/net40/Newtonsoft.Json.xml
vendored
Normal file
File diff suppressed because it is too large
Load Diff
BIN
test/Squirrel.Tests/fixtures/packages/Newtonsoft.Json.6.0.3/lib/net45/Newtonsoft.Json.dll
vendored
Normal file
BIN
test/Squirrel.Tests/fixtures/packages/Newtonsoft.Json.6.0.3/lib/net45/Newtonsoft.Json.dll
vendored
Normal file
Binary file not shown.
8488
test/Squirrel.Tests/fixtures/packages/Newtonsoft.Json.6.0.3/lib/net45/Newtonsoft.Json.xml
vendored
Normal file
8488
test/Squirrel.Tests/fixtures/packages/Newtonsoft.Json.6.0.3/lib/net45/Newtonsoft.Json.xml
vendored
Normal file
File diff suppressed because it is too large
Load Diff
BIN
test/Squirrel.Tests/fixtures/packages/Newtonsoft.Json.6.0.3/lib/netcore45/Newtonsoft.Json.dll
vendored
Normal file
BIN
test/Squirrel.Tests/fixtures/packages/Newtonsoft.Json.6.0.3/lib/netcore45/Newtonsoft.Json.dll
vendored
Normal file
Binary file not shown.
8013
test/Squirrel.Tests/fixtures/packages/Newtonsoft.Json.6.0.3/lib/netcore45/Newtonsoft.Json.xml
vendored
Normal file
8013
test/Squirrel.Tests/fixtures/packages/Newtonsoft.Json.6.0.3/lib/netcore45/Newtonsoft.Json.xml
vendored
Normal file
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
93
test/Squirrel.Tests/fixtures/packages/Newtonsoft.Json.6.0.3/tools/install.ps1
vendored
Normal file
93
test/Squirrel.Tests/fixtures/packages/Newtonsoft.Json.6.0.3/tools/install.ps1
vendored
Normal file
@@ -0,0 +1,93 @@
|
||||
param($installPath, $toolsPath, $package, $project)
|
||||
|
||||
# open json.net splash page on package install
|
||||
# don't open if json.net is installed as a dependency
|
||||
|
||||
try
|
||||
{
|
||||
$url = "http://james.newtonking.com/json"
|
||||
$dte2 = Get-Interface $dte ([EnvDTE80.DTE2])
|
||||
|
||||
if ($dte2.ActiveWindow.Caption -eq "Package Manager Console")
|
||||
{
|
||||
# user is installing from VS NuGet console
|
||||
# get reference to the window, the console host and the input history
|
||||
# show webpage if "install-package newtonsoft.json" was last input
|
||||
|
||||
$consoleWindow = $(Get-VSComponentModel).GetService([NuGetConsole.IPowerConsoleWindow])
|
||||
|
||||
$props = $consoleWindow.GetType().GetProperties([System.Reflection.BindingFlags]::Instance -bor `
|
||||
[System.Reflection.BindingFlags]::NonPublic)
|
||||
|
||||
$prop = $props | ? { $_.Name -eq "ActiveHostInfo" } | select -first 1
|
||||
if ($prop -eq $null) { return }
|
||||
|
||||
$hostInfo = $prop.GetValue($consoleWindow)
|
||||
if ($hostInfo -eq $null) { return }
|
||||
|
||||
$history = $hostInfo.WpfConsole.InputHistory.History
|
||||
|
||||
$lastCommand = $history | select -last 1
|
||||
|
||||
if ($lastCommand)
|
||||
{
|
||||
$lastCommand = $lastCommand.Trim().ToLower()
|
||||
if ($lastCommand.StartsWith("install-package") -and $lastCommand.Contains("newtonsoft.json"))
|
||||
{
|
||||
$dte2.ItemOperations.Navigate($url) | Out-Null
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
# user is installing from VS NuGet dialog
|
||||
# get reference to the window, then smart output console provider
|
||||
# show webpage if messages in buffered console contains "installing...newtonsoft.json" in last operation
|
||||
|
||||
$instanceField = [NuGet.Dialog.PackageManagerWindow].GetField("CurrentInstance", [System.Reflection.BindingFlags]::Static -bor `
|
||||
[System.Reflection.BindingFlags]::NonPublic)
|
||||
$consoleField = [NuGet.Dialog.PackageManagerWindow].GetField("_smartOutputConsoleProvider", [System.Reflection.BindingFlags]::Instance -bor `
|
||||
[System.Reflection.BindingFlags]::NonPublic)
|
||||
if ($instanceField -eq $null -or $consoleField -eq $null) { return }
|
||||
|
||||
$instance = $instanceField.GetValue($null)
|
||||
if ($instance -eq $null) { return }
|
||||
|
||||
$consoleProvider = $consoleField.GetValue($instance)
|
||||
if ($consoleProvider -eq $null) { return }
|
||||
|
||||
$console = $consoleProvider.CreateOutputConsole($false)
|
||||
|
||||
$messagesField = $console.GetType().GetField("_messages", [System.Reflection.BindingFlags]::Instance -bor `
|
||||
[System.Reflection.BindingFlags]::NonPublic)
|
||||
if ($messagesField -eq $null) { return }
|
||||
|
||||
$messages = $messagesField.GetValue($console)
|
||||
if ($messages -eq $null) { return }
|
||||
|
||||
$operations = $messages -split "=============================="
|
||||
|
||||
$lastOperation = $operations | select -last 1
|
||||
|
||||
if ($lastOperation)
|
||||
{
|
||||
$lastOperation = $lastOperation.ToLower()
|
||||
|
||||
$lines = $lastOperation -split "`r`n"
|
||||
|
||||
$installMatch = $lines | ? { $_.StartsWith("------- installing...newtonsoft.json ") } | select -first 1
|
||||
|
||||
if ($installMatch)
|
||||
{
|
||||
$dte2.ItemOperations.Navigate($url) | Out-Null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
# stop potential errors from bubbling up
|
||||
# worst case the splash page won't open
|
||||
}
|
||||
|
||||
# yolo
|
||||
BIN
test/Squirrel.Tests/fixtures/packages/NuGet.Core.2.8.2/NuGet.Core.2.8.2.nupkg
vendored
Normal file
BIN
test/Squirrel.Tests/fixtures/packages/NuGet.Core.2.8.2/NuGet.Core.2.8.2.nupkg
vendored
Normal file
Binary file not shown.
BIN
test/Squirrel.Tests/fixtures/packages/NuGet.Core.2.8.2/lib/net40-Client/NuGet.Core.dll
vendored
Normal file
BIN
test/Squirrel.Tests/fixtures/packages/NuGet.Core.2.8.2/lib/net40-Client/NuGet.Core.dll
vendored
Normal file
Binary file not shown.
BIN
test/Squirrel.Tests/fixtures/packages/Splat.1.4.0/Splat.1.4.0.nupkg
vendored
Normal file
BIN
test/Squirrel.Tests/fixtures/packages/Splat.1.4.0/Splat.1.4.0.nupkg
vendored
Normal file
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user