Skip to content

Commit

Permalink
Merge branch 'stable'
Browse files Browse the repository at this point in the history
* stable:
  (doc) update CHANGELOG/nuspec
  (maint) formatting
  (GH-1248) Fix - multiple sources w/same base url fail
  (doc) CONTRIBUTING - automated testing
  (doc) CONTRIBUTING - build artifacts
  (doc) Testing - note frameworks used
  (GH-1315) Skip AutoUninstaller if no uninstall string
  (doc) update CHANGELOG/nuspec
  • Loading branch information
ferventcoder committed Jun 1, 2017
2 parents 43fea49 + 79e4245 commit 5f18c35
Show file tree
Hide file tree
Showing 8 changed files with 248 additions and 18 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,22 @@ This covers changes for the "chocolatey" and "chocolatey.lib" packages, which ar

## [0.10.6](https://github.com/chocolatey/choco/issues?q=milestone%3A0.10.6+is%3Aclosed) (unreleased)

This release includes fixes and adjustments to the API to make it more usable. Search / List has also been improved with the data that it returns when verbose/detailed, along with info always returning a package with information instead of erroring sometimes. The search results from the community package repository now match what you see on the website.

### BUG FIXES

* Fix - choco.exe.manifest is ignored because it is extracted AFTER first choco.exe access - see [#1292](https://github.com/chocolatey/choco/issues/1292)
* Fix - Chocolatey config changes in 0.10.4+ - The process cannot access the file because it is being used by another process - see [#1241](https://github.com/chocolatey/choco/issues/1241)
* Fix - PowerShell sees authenticode hash as changed in scripts that are UTF8 (w/out BOM) that contain unicode characters - see [#1225](https://github.com/chocolatey/choco/issues/1225)
* Fix - Chocolatey timed out immediately when execution timeout was infinite (0) - see [#1224](https://github.com/chocolatey/choco/issues/1224)
* Fix - Multiple authenticated sources with same base url fail when authentication is different - see [#1248](https://github.com/chocolatey/choco/issues/1248)
* Fix - choco list / search / info - Some packages can't be found - see [#1004](https://github.com/chocolatey/choco/issues/1004)
* Fix - chocolatey.config gets corrupted when multiple processes access simultaneously - see [#1258](https://github.com/chocolatey/choco/issues/1258)
* Fix - Update ShimGen to 0.8.x to address some issues - see [#1243](https://github.com/chocolatey/choco/issues/1243)
* Fix - AutoUninstaller should skip uninstall keys if they are empty - see [#1315](https://github.com/chocolatey/choco/issues/1315)
* Fix - Trace logging should only occur on when trace is enabled - see [#1309](https://github.com/chocolatey/choco/issues/1309)
* Fix - RefreshEnv.cmd doesn't set the correct PATH - see [#1227](https://github.com/chocolatey/choco/issues/1227)
* Fix - choco new generates uninstall template with wrong use of registry key variable - see [#1304](https://github.com/chocolatey/choco/issues/1304)
* [API] Fix- chocolatey.lib nuget package has incorrect documentation xml - see [#1247](https://github.com/chocolatey/choco/issues/1247)
* [API] Fix - Chocolatey file cache still adds a 'chocolatey' directory on each install - see [#1231](https://github.com/chocolatey/choco/issues/1231)
* [API] Fix - List and Count should implement similar functionality as run - see [#1298](https://github.com/chocolatey/choco/issues/1298)
Expand Down
43 changes: 43 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ The Chocolatey team has very explicit information here regarding the process for
- [PowerShell](#powershell)
- [Debugging / Testing](#debugging--testing)
- [Visual Studio](#visual-studio)
- [Automated Tests](#automated-tests)
- [Chocolatey Build](#chocolatey-build)
- [Prepare Commits](#prepare-commits)
- [Submit Pull Request (PR)](#submit-pull-request-pr)
Expand Down Expand Up @@ -157,12 +158,54 @@ When you are using Visual Studio, ensure the following:
* Use `Debug` configuration - debug configuration keeps your local changes separate from the machine installed Chocolatey.
* `chocolatey.console` is the project you are looking to run.
* If you make changes to anything that is in `chocolatey.resources`, delete the folder in `chocolatey.console\bin\Debug` that corresponds to where you've made changes as Chocolatey does not automatically detect changes in the files it is extracting from resource manifests.
* The automated testing framework that Chocolatey uses is [NUnit](https://www.nunit.org/), [TinySpec](https://www.nuget.org/packages/TinySpec.NUnit), [Moq](https://www.nuget.org/packages/moq), and [Should](https://www.nuget.org/packages/Should/). Do not be thrown off thinking it using something else based on seeing `Fact` attributes for specs/tests. That is TinySpec.
* For a good understanding of all frameworks used, please see [CREDITS](https://github.com/chocolatey/choco/blob/master/docs/legal/CREDITS.md)

##### Automated Tests

> "Testing doesn't prove the absence of bugs, they can only prove code works in the way you've tested."
The design was to get the testing framework out of the way and make it easy to swap out should it ever need to be (the former is the important goal). We test behaviors of the system, which doesn't simply mean ensuring code coverage. It means we want to see how the system behaves under certain behaviors. As you may see from looking over the tests, we have an interesting way of setting up our specs. We recommend importing the ReSharper templates in `docs\resharper_templates`. This will make adding specs and new spec files quite a bit easier.

The method of testing as you will see is a file that contains many test classes (scenarios) that set up and perform a behavior, then perform one or more validations (tests/facts) on that scenario. Typically when in a unit test suite, there would be a file for every representative class in the production code. You may not see this as much in this codebase as there are areas that could use more coverage.

We recognize the need for a very tight feedback loop (running and debugging tests right inside Visual Studio). Some great tools for running and debugging automated tests are [TestDriven.NET](http://www.testdriven.net/) and [ReSharper](https://www.jetbrains.com/resharper/) (you only need one, although both are recommended for development). We recommend TestDriven over other tools as it is absolutely wonderful in what it does.

With the way the testing framework is designed, it is helpful to gain an understanding on how you can debug into tests. There are a couple of known oddities when it comes to trying to run tests in Visual Studio:

* You can run a test or tests within a class.
* You can also right click on a folder (and solution folder), a project, or the solution and run tests.
* You can ***not*** click on a file and attempt to run/debug automated tests. You will see the following message: "The target type doesn't contain tests from a known test framework or a 'Main' method."
* You also cannot run all tests within a file by selecting somewhere outside a testing class and attempting to run tests. You will see the message above.

Some quick notes on testing terminology (still a WIP):

* Testing - anything done to test, whether manual, automated, or otherwise.
* Automated Testing - Any type of written test that can be run in an automated way, typically in the form of C# tests.
* Spec / Fact / Observation - these are synonyms for a test or validation.
* System Under Test (SUT) - the code or concern you are testing.
* Mock / Fake / Stub / Double - an object that provides a known state back to the system under test when the system under test interacts with other objects. This can be done with unit and whitebox integration testing. This allows for actual unit testing as most units (classes/functions) depend on working with other units (classes/functions) to get or set information and state. While each of [these are slightly different](https://martinfowler.com/articles/mocksArentStubs.html), the basic functionality is that they are standing in for other production code.
* Concern - an area of production code you are testing in e.g. "Concern for AutoUninstallerService".
* Regression Test Suite / Regression Suite - The automated tests that are in the form of code.
* Whitebox Testing - tests where you access the internals of the application.
* Unit Testing - We define a unit as a class and a method in C#. In PowerShell this is per function. If it involves another class or function, you have graduated to an integration. This is where Mocks come in to ensure no outside state is introduced.
* Whitebox Integration Testing - testing anything that is more than a unit.
* System Integration Testing - testing anything that goes out of the bounds of the written production code. Typically when running the code to get or set some state is where you will see this. And yes, even using DateTime.Now counts as system integration testing as it accesses something external to the application. This is why you will see we insulate those calls to something in the application so they can be easily tested against.
* Blackbox Testing - tests where you do not access internals of the application
* Physical Integration Testing - This is where you are testing the application with other components such as config files.
* Blackbox Integration Testing / End to End Testing - This is where you are testing inputs and outputs of the system.

As far as testing goes, unit tests are extremely quick feedback and great for longer term maintenance, where black box tests give you the most coverage, but are the slowest feedback loops and typically the most frail. Each area of testing has strengths and weaknesses and it's good to understand each of them.


**NOTE**: One of the hardest forms of testing is unit testing, as it almost always requires faking out other parts of the system (also known as mocking).

#### Chocolatey Build

**NOTE:** When you are doing this, we almost always recommend you take the output of the build to another machine to do the testing, like the [Chocolatey Test Environment](https://github.com/chocolatey/chocolatey-test-environment).

* Run `build.bat`.
* There is a detailed log of the output in both `build_output` and `code_drop\build_artifacts`. The `build_artifacts` folders contain a lot of detail with each individual tool's output and reporting (helpful when wanting to see a visual of what tests failed).
* There are two folders created - `build_output` and `code_drop`. You are looking for `code_drop\chocolatey\console` or `code_drop\nuget`. The `choco.exe` file contains everything it needs, but it does unpack the manifest on first use, so you could run into [#1292](https://github.com/chocolatey/choco/issues/1292).
* You will need to pass `--allow-unofficial-build` for it to work when built with release mode.
* You can also try `build.debug.bat` - note that it is newer and it may have an issue or two. It doesn't require `--allow-unofficial-build` as the binaries are built for debugging.
Expand Down
21 changes: 21 additions & 0 deletions docs/resharper_templates/Fact_LiveTemplate.DotSettings
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=F821E739F6F97246A2628CDAECFF2B05/@KeyIndexDefined">True</s:Boolean>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=F821E739F6F97246A2628CDAECFF2B05/Shortcut/@EntryValue">fact</s:String>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=F821E739F6F97246A2628CDAECFF2B05/Description/@EntryValue">creates a fact</s:String>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=F821E739F6F97246A2628CDAECFF2B05/Text/@EntryValue">&#xD;
[Fact]&#xD;
public void should_$result_in$()&#xD;
{&#xD;
$END$&#xD;
}&#xD;
&#xD;
</s:String>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=F821E739F6F97246A2628CDAECFF2B05/Reformat/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=F821E739F6F97246A2628CDAECFF2B05/ShortenQualifiedReferences/@EntryValue">True</s:Boolean>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=F821E739F6F97246A2628CDAECFF2B05/Categories/=Imported_00204_002F20_002F2014/@EntryIndexedValue">Imported 4/20/2014</s:String>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=F821E739F6F97246A2628CDAECFF2B05/Applicability/=Live/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=F821E739F6F97246A2628CDAECFF2B05/Scope/=C3001E7C0DA78E4487072B7E050D86C5/@KeyIndexDefined">True</s:Boolean>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=F821E739F6F97246A2628CDAECFF2B05/Scope/=C3001E7C0DA78E4487072B7E050D86C5/Type/@EntryValue">InCSharpFile</s:String>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=F821E739F6F97246A2628CDAECFF2B05/Scope/=C3001E7C0DA78E4487072B7E050D86C5/CustomProperties/=minimumLanguageVersion/@EntryIndexedValue">2.0</s:String>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=F821E739F6F97246A2628CDAECFF2B05/Field/=result_005Fin/@KeyIndexDefined">True</s:Boolean>
<s:Int64 x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=F821E739F6F97246A2628CDAECFF2B05/Field/=result_005Fin/Order/@EntryValue">0</s:Int64></wpf:ResourceDictionary>
67 changes: 67 additions & 0 deletions docs/resharper_templates/TinySpecSpec_FileTemplate.DotSettings
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=66BEC5AFAD78714BA148EDF64BFB8F1B/@KeyIndexDefined">True</s:Boolean>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=66BEC5AFAD78714BA148EDF64BFB8F1B/Description/@EntryValue">TinySpecSpec</s:String>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=66BEC5AFAD78714BA148EDF64BFB8F1B/Text/@EntryValue">namespace $namespace$&#xD;
{&#xD;
using Moq;&#xD;
using Should;&#xD;
&#xD;
public class $name$&#xD;
{&#xD;
public abstract class $name$Base : TinySpec&#xD;
{&#xD;
protected $item_under_test$ itemUnderTest;&#xD;
&#xD;
public override void Context()&#xD;
{&#xD;
itemUnderTest = new $item_under_test$();&#xD;
}&#xD;
}&#xD;
&#xD;
public class when_$item_under_test$_$has_context$ : $name$Base&#xD;
{&#xD;
private string result;&#xD;
&#xD;
public override void Context()&#xD;
{&#xD;
base.Context();&#xD;
}&#xD;
&#xD;
public override void Because()&#xD;
{&#xD;
result = $this_happened$&#xD;
}&#xD;
&#xD;
[Fact]&#xD;
public void should_$result_in$()&#xD;
{&#xD;
$END$&#xD;
}&#xD;
}&#xD;
}&#xD;
}</s:String>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=66BEC5AFAD78714BA148EDF64BFB8F1B/Reformat/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=66BEC5AFAD78714BA148EDF64BFB8F1B/ShortenQualifiedReferences/@EntryValue">True</s:Boolean>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=66BEC5AFAD78714BA148EDF64BFB8F1B/Categories/=Imported_00204_002F20_002F2014/@EntryIndexedValue">Imported 4/20/2014</s:String>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=66BEC5AFAD78714BA148EDF64BFB8F1B/CustomProperties/=Extension/@EntryIndexedValue">cs</s:String>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=66BEC5AFAD78714BA148EDF64BFB8F1B/CustomProperties/=FileName/@EntryIndexedValue">Spec</s:String>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=66BEC5AFAD78714BA148EDF64BFB8F1B/CustomProperties/=ValidateFileName/@EntryIndexedValue">False</s:String>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=66BEC5AFAD78714BA148EDF64BFB8F1B/Applicability/=File/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=66BEC5AFAD78714BA148EDF64BFB8F1B/Scope/=E8F0594528C33E45BBFEC6CFE851095D/@KeyIndexDefined">True</s:Boolean>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=66BEC5AFAD78714BA148EDF64BFB8F1B/Scope/=E8F0594528C33E45BBFEC6CFE851095D/Type/@EntryValue">InCSharpProjectFile</s:String>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=66BEC5AFAD78714BA148EDF64BFB8F1B/Field/=namespace/@KeyIndexDefined">True</s:Boolean>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=66BEC5AFAD78714BA148EDF64BFB8F1B/Field/=namespace/Expression/@EntryValue">fileDefaultNamespace()</s:String>
<s:Int64 x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=66BEC5AFAD78714BA148EDF64BFB8F1B/Field/=namespace/InitialRange/@EntryValue">-1</s:Int64>
<s:Int64 x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=66BEC5AFAD78714BA148EDF64BFB8F1B/Field/=namespace/Order/@EntryValue">0</s:Int64>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=66BEC5AFAD78714BA148EDF64BFB8F1B/Field/=name/@KeyIndexDefined">True</s:Boolean>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=66BEC5AFAD78714BA148EDF64BFB8F1B/Field/=name/Expression/@EntryValue">getFileNameWithoutExtension()</s:String>
<s:Int64 x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=66BEC5AFAD78714BA148EDF64BFB8F1B/Field/=name/InitialRange/@EntryValue">-1</s:Int64>
<s:Int64 x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=66BEC5AFAD78714BA148EDF64BFB8F1B/Field/=name/Order/@EntryValue">1</s:Int64>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=66BEC5AFAD78714BA148EDF64BFB8F1B/Field/=item_005Funder_005Ftest/@KeyIndexDefined">True</s:Boolean>
<s:Int64 x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=66BEC5AFAD78714BA148EDF64BFB8F1B/Field/=item_005Funder_005Ftest/Order/@EntryValue">2</s:Int64>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=66BEC5AFAD78714BA148EDF64BFB8F1B/Field/=has_005Fcontext/@KeyIndexDefined">True</s:Boolean>
<s:Int64 x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=66BEC5AFAD78714BA148EDF64BFB8F1B/Field/=has_005Fcontext/Order/@EntryValue">3</s:Int64>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=66BEC5AFAD78714BA148EDF64BFB8F1B/Field/=this_005Fhappened/@KeyIndexDefined">True</s:Boolean>
<s:Int64 x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=66BEC5AFAD78714BA148EDF64BFB8F1B/Field/=this_005Fhappened/Order/@EntryValue">4</s:Int64>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=66BEC5AFAD78714BA148EDF64BFB8F1B/Field/=result_005Fin/@KeyIndexDefined">True</s:Boolean>
<s:Int64 x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=66BEC5AFAD78714BA148EDF64BFB8F1B/Field/=result_005Fin/Order/@EntryValue">5</s:Int64></wpf:ResourceDictionary>
Loading

0 comments on commit 5f18c35

Please sign in to comment.