Skip to content

Commit

Permalink
(GH-452) Fix broken pin command
Browse files Browse the repository at this point in the history
Choco pin list used to ensure that the output from the local `list_run`
command did not output on stdout. However a commit in GH-132 caused pin
to start outputting the list output as well as pin output. Fix this by
adding `config.QuietOutput = true;` around the call to List_run.

Also add integration spec scenarios to ensure this is not subject to
happen again.
  • Loading branch information
ferventcoder committed Oct 5, 2015
1 parent a330a00 commit 0310987
Show file tree
Hide file tree
Showing 5 changed files with 365 additions and 1 deletion.
41 changes: 41 additions & 0 deletions Scenarios.md
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,47 @@
* should contain tags
* should not contain packages and versions with a pipe between them

### ChocolateyPinCommand [ 9 Scenario(s), 12 Observation(s) ]

#### when listing pins with an existing pin

* should contain existing pin messages
* should not contain list results

#### when listing pins with existing pins

* should contain a pin message for each existing pin
* should not contain list results

#### when listing pins with no pins

* should not contain any pins by default
* should not contain list results

#### when removing a pin for a non installed package

* should throw an error about not finding the package

#### when removing a pin for a pinned package

* should contain success message

#### when removing a pin for an unpinned package

* should contain nothing to do message

#### when setting a pin for a non installed package

* should throw an error about not finding the package

#### when setting a pin for an already pinned package

* should contain nothing to do message

#### when setting a pin for an installed package

* should contain success message

### ChocolateyUninstallCommand [ 13 Scenario(s), 90 Observation(s) ]

#### when force uninstalling a package
Expand Down
8 changes: 8 additions & 0 deletions src/chocolatey.tests.integration/Scenario.cs
Original file line number Diff line number Diff line change
Expand Up @@ -174,5 +174,13 @@ public static ChocolateyConfiguration list()

return config;
}

public static ChocolateyConfiguration pin()
{
var config = baseline_configuration();
config.CommandName = CommandNameType.pin.to_string();

return config;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@
<Compile Include="Scenario.cs" />
<Compile Include="scenarios\InstallScenarios.cs" />
<Compile Include="scenarios\ListScenarios.cs" />
<Compile Include="scenarios\PinScenarios.cs" />
<Compile Include="scenarios\UninstallScenarios.cs" />
<Compile Include="scenarios\UpgradeScenarios.cs" />
<Compile Include="TODO.cs" />
Expand Down
306 changes: 306 additions & 0 deletions src/chocolatey.tests.integration/scenarios/PinScenarios.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,306 @@
// Copyright © 2011 - Present RealDimensions Software, LLC
//
// 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.

namespace chocolatey.tests.integration.scenarios
{
using System;
using System.Collections.Generic;
using System.Linq;
using NuGet;
using Should;
using bdddoc.core;
using chocolatey.infrastructure.app;
using chocolatey.infrastructure.app.attributes;
using chocolatey.infrastructure.app.commands;
using chocolatey.infrastructure.app.configuration;
using chocolatey.infrastructure.app.domain;
using chocolatey.infrastructure.commands;
using chocolatey.infrastructure.results;

public class PinScenarios
{
public abstract class ScenariosBase : TinySpec
{
protected IList<PackageResult> Results;
protected ChocolateyConfiguration Configuration;
protected ChocolateyPinCommand Service;

public override void Context()
{
Configuration = Scenario.pin();
Scenario.reset(Configuration);
Scenario.add_packages_to_source_location(Configuration, Configuration.Input + "*" + Constants.PackageExtension);
Scenario.add_packages_to_source_location(Configuration, "installpackage*" + Constants.PackageExtension);
Scenario.install_package(Configuration, "installpackage", "1.0.0");
Scenario.install_package(Configuration, "upgradepackage", "1.0.0");
Scenario.install_package(Configuration, "hasdependency", "1.0.0");

var commands = NUnitSetup.Container.GetAllInstances<ICommand>();
Service = commands.Where(
(c) =>
{
var attributes = c.GetType().GetCustomAttributes(typeof(CommandForAttribute), false);
return attributes.Cast<CommandForAttribute>().Any(attribute => attribute.CommandName.is_equal_to(Configuration.CommandName));
}).FirstOrDefault() as ChocolateyPinCommand;

Configuration.Sources = ApplicationParameters.PackagesLocation;
Configuration.ListCommand.LocalOnly = true;
Configuration.AllVersions = true;
Configuration.Prerelease = true;
}
}

[Concern(typeof(ChocolateyPinCommand))]
public class when_listing_pins_with_no_pins : ScenariosBase
{
public override void Context()
{
base.Context();
Configuration.PinCommand.Command = PinCommandType.list;
}

public override void Because()
{
MockLogger.reset();
Service.run(Configuration);
}

[Fact]
public void should_not_contain_list_results()
{
MockLogger.contains_message("upgradepackage 1.0.0", LogLevel.Info).ShouldBeFalse();
MockLogger.contains_message("upgradepackage 1.0.0", LogLevel.Warn).ShouldBeFalse();
MockLogger.contains_message("upgradepackage 1.0.0", LogLevel.Error).ShouldBeFalse();
}

[Fact]
public void should_not_contain_any_pins_by_default()
{
MockLogger.contains_message("upgradepackage|1.0.0").ShouldBeFalse();
}
}

[Concern(typeof(ChocolateyPinCommand))]
public class when_listing_pins_with_an_existing_pin : ScenariosBase
{
public override void Context()
{
base.Context();
Configuration.PinCommand.Command = PinCommandType.add;
Configuration.PinCommand.Name = "upgradepackage";
Service.run(Configuration);
Configuration.PinCommand.Command = PinCommandType.list;
}

public override void Because()
{
MockLogger.reset();
Service.run(Configuration);
}

[Fact]
public void should_not_contain_list_results()
{
MockLogger.contains_message("upgradepackage 1.0.0", LogLevel.Info).ShouldBeFalse();
MockLogger.contains_message("upgradepackage 1.0.0", LogLevel.Warn).ShouldBeFalse();
MockLogger.contains_message("upgradepackage 1.0.0", LogLevel.Error).ShouldBeFalse();
}

[Fact]
public void should_contain_existing_pin_messages()
{
MockLogger.contains_message("upgradepackage|1.0.0").ShouldBeTrue();
}
}

[Concern(typeof(ChocolateyPinCommand))]
public class when_listing_pins_with_existing_pins : ScenariosBase
{
public override void Context()
{
base.Context();
Configuration.PinCommand.Command = PinCommandType.add;
Configuration.PinCommand.Name = "upgradepackage";
Service.run(Configuration);
Configuration.PinCommand.Name = "installpackage";
Service.run(Configuration);
Configuration.PinCommand.Command = PinCommandType.list;
}

public override void Because()
{
MockLogger.reset();
Service.run(Configuration);
}

[Fact]
public void should_not_contain_list_results()
{
MockLogger.contains_message("upgradepackage 1.0.0", LogLevel.Info).ShouldBeFalse();
MockLogger.contains_message("upgradepackage 1.0.0", LogLevel.Warn).ShouldBeFalse();
MockLogger.contains_message("upgradepackage 1.0.0", LogLevel.Error).ShouldBeFalse();
}

[Fact]
public void should_contain_a_pin_message_for_each_existing_pin()
{
MockLogger.contains_message("installpackage|1.0.0").ShouldBeTrue();
MockLogger.contains_message("upgradepackage|1.0.0").ShouldBeTrue();
}
}

[Concern(typeof(ChocolateyPinCommand))]
public class when_setting_a_pin_for_an_installed_package : ScenariosBase
{
public override void Context()
{
base.Context();
Configuration.PinCommand.Command = PinCommandType.add;
Configuration.PinCommand.Name = "upgradepackage";
}

public override void Because()
{
MockLogger.reset();
Service.run(Configuration);
}

[Fact]
public void should_contain_success_message()
{
MockLogger.contains_message("Successfully added a pin for upgradepackage").ShouldBeTrue();
}
}

[Concern(typeof(ChocolateyPinCommand))]
public class when_setting_a_pin_for_an_already_pinned_package : ScenariosBase
{
public override void Context()
{
base.Context();
Configuration.PinCommand.Command = PinCommandType.add;
Configuration.PinCommand.Name = "upgradepackage";
Service.run(Configuration);
}

public override void Because()
{
MockLogger.reset();
Service.run(Configuration);
}

[Fact]
public void should_contain_nothing_to_do_message()
{
MockLogger.contains_message("Nothing to change. Pin already set or removed.").ShouldBeTrue();
}
}

[Concern(typeof(ChocolateyPinCommand))]
public class when_setting_a_pin_for_a_non_installed_package : ScenariosBase
{
public override void Context()
{
base.Context();
Configuration.PinCommand.Command = PinCommandType.add;
Configuration.PinCommand.Name = "whatisthis";
}

public override void Because()
{
MockLogger.reset();
}

[ExpectedException(typeof(ApplicationException), ExpectedMessage = "Unable to find package named 'whatisthis' to pin. Please check to ensure it is installed.")]
[Fact]
public void should_throw_an_error_about_not_finding_the_package()
{
Service.run(Configuration);
}
}

[Concern(typeof(ChocolateyPinCommand))]
public class when_removing_a_pin_for_a_pinned_package : ScenariosBase
{
public override void Context()
{
base.Context();
Configuration.PinCommand.Command = PinCommandType.add;
Configuration.PinCommand.Name = "upgradepackage";
Service.run(Configuration);

Configuration.PinCommand.Command = PinCommandType.remove;
}

public override void Because()
{
MockLogger.reset();
Service.run(Configuration);
}

[Fact]
public void should_contain_success_message()
{
MockLogger.contains_message("Successfully removed a pin for upgradepackage").ShouldBeTrue();
}
}

[Concern(typeof(ChocolateyPinCommand))]
public class when_removing_a_pin_for_an_unpinned_package : ScenariosBase
{
public override void Context()
{
base.Context();
Configuration.PinCommand.Command = PinCommandType.remove;
Configuration.PinCommand.Name = "upgradepackage";
}

public override void Because()
{
MockLogger.reset();
Service.run(Configuration);
}

[Fact]
public void should_contain_nothing_to_do_message()
{
MockLogger.contains_message("Nothing to change. Pin already set or removed.").ShouldBeTrue();
}
}

[Concern(typeof(ChocolateyPinCommand))]
public class when_removing_a_pin_for_a_non_installed_package : ScenariosBase
{
public override void Context()
{
base.Context();
Configuration.PinCommand.Command = PinCommandType.remove;
Configuration.PinCommand.Name = "whatisthis";
}

public override void Because()
{
MockLogger.reset();
}

[ExpectedException(typeof(ApplicationException), ExpectedMessage = "Unable to find package named 'whatisthis' to pin. Please check to ensure it is installed.")]
[Fact]
public void should_throw_an_error_about_not_finding_the_package()
{
Service.run(Configuration);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,15 @@ public void run(ChocolateyConfiguration configuration)

public void list_pins(IPackageManager packageManager, ChocolateyConfiguration config)
{
foreach (var pkg in _nugetService.list_run(config))
var input = config.Input;
config.Input = string.Empty;
var quiet = config.QuietOutput;
config.QuietOutput = true;
var packages = _nugetService.list_run(config).ToList();
config.QuietOutput = quiet;
config.Input = input;

foreach (var pkg in packages.or_empty_list_if_null())
{
var pkgInfo = _packageInfoService.get_package_information(pkg.Package);
if (pkgInfo != null && pkgInfo.IsPinned)
Expand Down

0 comments on commit 0310987

Please sign in to comment.