Browse Source

Merge pull request #4 from CraigOates/0.3

0.3
master
Craig Oates 6 years ago committed by GitHub
parent
commit
e8f5d52c59
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      .gitignore
  2. 6
      SmoulderingBeachBall.sln
  3. 2
      SmoulderingBeachBall/InternalServices.fs
  4. 2
      SmoulderingBeachBall/ScratchPad.fsx
  5. 20
      SmoulderingBeachBallCLI/Validation.fs
  6. 41
      TestCentre/AssemblyInfo.fs
  7. 123
      TestCentre/ConsoleTests.fs
  8. 105
      TestCentre/LibraryTests.fs
  9. 15
      TestCentre/Script.fsx
  10. 116
      TestCentre/TestCentre.fsproj
  11. 16
      TestCentre/packages.config

3
.gitignore vendored

@ -3,6 +3,9 @@
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
# Project Specific Items
SavingTestArea/
# User-specific files
*.suo
*.user

6
SmoulderingBeachBall.sln

@ -7,6 +7,8 @@ Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "SmoulderingBeachBall", "Smo
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "SmoulderingBeachBallCLI", "SmoulderingBeachBallCLI\SmoulderingBeachBallCLI.fsproj", "{5C00D583-EF09-4FE6-A3FE-EB01454C0607}"
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "TestCentre", "TestCentre\TestCentre.fsproj", "{9EAEE0E6-1E90-4C44-AD22-E8CA727B3392}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -21,6 +23,10 @@ Global
{5C00D583-EF09-4FE6-A3FE-EB01454C0607}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5C00D583-EF09-4FE6-A3FE-EB01454C0607}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5C00D583-EF09-4FE6-A3FE-EB01454C0607}.Release|Any CPU.Build.0 = Release|Any CPU
{9EAEE0E6-1E90-4C44-AD22-E8CA727B3392}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9EAEE0E6-1E90-4C44-AD22-E8CA727B3392}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9EAEE0E6-1E90-4C44-AD22-E8CA727B3392}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9EAEE0E6-1E90-4C44-AD22-E8CA727B3392}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

2
SmoulderingBeachBall/InternalServices.fs

@ -44,7 +44,6 @@
let penPath = createBorderPath pen.Width spec
graphics.DrawLines (pen, penPath)
let drawFullOverlay (graphics: Graphics) (pen: Pen) spec =
drawBorder graphics pen spec
printfn "[INFO.] Adding full overlay to image..."
@ -70,7 +69,6 @@
sb.Append ".png" |> ignore
(sb.ToString ())
let drawImage spec =
let bitmap = new Bitmap (spec.width, spec.height)
let graphics = Graphics.FromImage (bitmap)

2
SmoulderingBeachBall/ScratchPad.fsx

@ -34,7 +34,7 @@ let imageSpec =
{ width = 500;
height = 500;
colour = Brushes.Yellow;
filePath = "C:/users/craig/desktop/test.png";
filePath = "C:/users/craig/desktop/";
// Change this to flip between border/full overlay or None.
overlay = Some fullOverlay }

20
SmoulderingBeachBallCLI/Validation.fs

@ -1,4 +1,4 @@
module internal Validation
module Validation
open System.Drawing
open SmoulderingBeachBall.Domain.DomainTypes
@ -16,11 +16,11 @@
"yellow", Brushes.Yellow;]
|> Map.ofList
let isColourValid (colour: string) =
let private isColourValid (colour: string) =
colourList
|> Map.containsKey (colour.ToLower())
let parseColour colour =
let private parseColour colour =
match (isColourValid colour) with
| true ->
colourList
@ -33,7 +33,7 @@
let getDesktopPath =
Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory)
let parsePath (path: string) =
let private parsePath (path: string) =
match path with
| path when ((path.ToLower()).Equals "desktop") -> getDesktopPath
| path when ((path.ToLower()).Equals "d") -> getDesktopPath
@ -52,7 +52,7 @@
}
spec
let parseOverlay (oType: string) =
let private parseOverlay (oType: string) =
match oType.ToLower() with
| "border" -> Border
| "b" -> Border
@ -60,16 +60,16 @@
| "f" -> Full
| _ -> invalidArg "Overlay Type" "The overlay type must be either 'border' or 'full'."
let buildOverlaySpec oColour (oType: string) =
let private buildOverlaySpec oColour (oType: string) =
let oSpec =
{ colour = parseColour oColour;
{ colour = parseColour oColour
overlayType = parseOverlay oType }
oSpec
let buildMainSpec iWidth iHeight mainColour path oSpec =
let private buildMainSpec iWidth iHeight mainColour path oSpec =
let spec =
{ width = iWidth;
height = iHeight;
{ width = iWidth
height = iHeight
colour = parseColour mainColour
filePath = parsePath path
overlay = oSpec }

41
TestCentre/AssemblyInfo.fs

@ -0,0 +1,41 @@
namespace TestCentre.AssemblyInfo
open System.Reflection
open System.Runtime.CompilerServices
open System.Runtime.InteropServices
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[<assembly: AssemblyTitle("Test Centre")>]
[<assembly: AssemblyDescription("A testing library for Smouldering Beach Ball solution.")>]
[<assembly: AssemblyConfiguration("")>]
[<assembly: AssemblyCompany("")>]
[<assembly: AssemblyProduct("TestCentre")>]
[<assembly: AssemblyCopyright("Copyright © 2018")>]
[<assembly: AssemblyTrademark("")>]
[<assembly: AssemblyCulture("")>]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[<assembly: ComVisible(false)>]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[<assembly: Guid("9eaee0e6-1e90-4c44-ad22-e8ca727b3392")>]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [<assembly: AssemblyVersion("1.0.*")>]
[<assembly: AssemblyVersion("0.3.0.0")>]
[<assembly: AssemblyFileVersion("0.3.0.0")>]
do
()

123
TestCentre/ConsoleTests.fs

@ -0,0 +1,123 @@
namespace ConsoleTests
module PropertyTests =
open FsCheck.Xunit
open Validation
open System
open SmoulderingBeachBall.Domain.DomainTypes
open System.Drawing
(* The functions without the "Property" attribute are not for testing.
They generate the test data used in the (property) tests.
Please be careful when removing any of these types of functions.
They are the ones not marked with the "Property" attribute.
Also, the intention is to keep these functions seperate from the tests.
Until it is not practical to keep them in this module, the default place to keep them is above the tests. With that said, it is just a guide.
Use your best judgement when adding new "helper" functions.
This applies to the UnitTests module, thanks. *)
let randomInt () = Random().Next()
let randomColour () =
colourList
|> Map.toList
|> List.item (Random().Next(colourList.Count))
let overlays = [|"none"; "n"; "b"; "border"; "full"; "f"|]
let noOverlay () = overlays.[Random().Next(0, 1)]
let borderOverlay () = overlays.[Random().Next(2, 3)]
let fullOverlay () = overlays.[Random().Next(4, 5)]
[<Property>]
let ``Can create an intended default image spec`` () =
let width = randomInt ()
let height = randomInt ()
let oSpec =
{ colour = Brushes.Black
overlayType = Full }
let defaultSpec =
{ width = width
height = height
colour = Brushes.AntiqueWhite
filePath = getDesktopPath
overlay = Some oSpec
}
let spec = buildDefaultSpec width height
defaultSpec = spec
[<Property>]
let ``Can create an image spec with border`` () =
let width = randomInt ()
let height = randomInt ()
let mainColour = randomColour ()
let overlayColour = randomColour ()
let overlay = borderOverlay ()
let oSpec =
{ colour = (snd) overlayColour
overlayType = Border }
let expectedSpec =
{ width = width
height = height
colour = (snd) mainColour
filePath = getDesktopPath
overlay = Some oSpec
}
let spec =
buildSpec width height (fst mainColour) (fst overlayColour) overlay getDesktopPath
expectedSpec = spec
[<Property>]
let ``Can create an image spec with full overlay`` () =
let width = randomInt ()
let height = randomInt ()
let mainColour = randomColour ()
let overlayColour = randomColour ()
let overlay = fullOverlay ()
let oSpec =
{ colour = snd overlayColour
overlayType = Full }
let expectedSpec =
{ width = width
height = height
colour = snd mainColour
filePath = getDesktopPath
overlay = Some oSpec }
let spec =
buildSpec width height (fst mainColour) (fst overlayColour) overlay getDesktopPath
expectedSpec = spec
[<Property>]
let ``Can create an image spec with no overlay`` () =
let width = randomInt ()
let height = randomInt ()
let colour = randomColour ()
let overlay = noOverlay ()
let expectedSpec =
{ width = width
height = height
colour = snd colour
filePath = getDesktopPath
overlay = option.None }
let spec =
buildSpec width height (fst colour) (fst colour) overlay getDesktopPath
expectedSpec = spec
module UnitTests =
open Xunit
open Validation
open System
[<Fact>]
let ``Colour map is not empty`` () =
Assert.NotEmpty colourList
[<Fact>]
let ``Can retrieve the path to users desktop`` () =
let expectedPath =
Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory)
Assert.Equal (expectedPath, getDesktopPath)

105
TestCentre/LibraryTests.fs

@ -0,0 +1,105 @@
namespace LibraryTests
module PropertyTests =
open FsCheck.Xunit
open System
open System.Drawing
open SmoulderingBeachBall.Domain.DomainTypes
open System.Reflection
open SmoulderingBeachBall.Services
open System.IO
open System.Threading
open FsCheck
(* '3000' is an arbitary value. It is used to keep the testing times sane.
This function is used to randomly generate image sizes but you do not need to use it.
The project can handle larger numbers than '3000' but processing takes longer.
If you decide to change it, please keep an eye on the saving time.
When a image is too big, the project cannot write it to disc fast enough --
sometimes it is because of IO constraints.
This means the tests checking for this fail/error will think the image does not exist.
To resolved this, add a Thread.Sleep call to the affected tests.
Just be aware, the length of sleep-time depends on the size of the image.
Also, problems tends to arise around the 15,000 mark.
*)
let randomInt () = Random().Next(3000)
let saveLocation = __SOURCE_DIRECTORY__ + "/SavingTestArea/"
let allColours =
let properties =
typeof<Brushes>.GetProperties(BindingFlags.Public ||| BindingFlags.Static)
let colours =
seq { for prop in properties -> prop}
|> Seq.toArray
colours
let randomColour () =
let item = allColours.[Random().Next(allColours.Length)]
item.GetValue(null, null)
let fileSaved width height =
saveLocation + width + "x" + height + ".png"
|> File.Exists
// To manually clear out the SavingTestArea folder, use this function in script.fsx.
let resetSavingTestArea () =
let files = Directory.GetFileSystemEntries(saveLocation)
match files.Length with
| 0 -> ()
| _ ->
files
|> Array.iter (fun f -> File.Delete(f))
let buildBorderOverlay () =
Thread.Sleep 100 // Helps generate better colour variation.
{ colour = randomColour () :?> Brush
overlayType = Border }
let buildFullOverlay () =
Thread.Sleep 100 // Helps generate better colour variation.
{ colour = randomColour () :?> Brush
overlayType = Full }
(* Please non-test functions above the test functions.
See ConsoleTests.fs for the extended comment -- regarding function placement. *)
[<Property>]
let ``Can create an image with no overlay`` () =
resetSavingTestArea ()
let spec =
{ // See note accompanying 'randomInt' function for constraints information.
width = randomInt ()
height = randomInt ()
colour = randomColour () :?> Brush
filePath = saveLocation
overlay = None }
makeImage spec |> Async.RunSynchronously
fileSaved (spec.width.ToString()) (spec.height.ToString()) = true
[<Property>]
let ``Can create an image with border`` () =
resetSavingTestArea ()
let spec =
{ // See note accompanying 'randomInt' function for constraints information.
width = randomInt ()
height = randomInt ()
colour = randomColour () :?> Brush
filePath = saveLocation
overlay = Some (buildBorderOverlay ()) }
makeImage spec |> Async.RunSynchronously
fileSaved (spec.width.ToString()) (spec.height.ToString()) = true
[<Property>]
let ``Can create an image with a full overlay`` () =
resetSavingTestArea ()
let spec =
{ // See note accompanying 'randomInt' function for constraints information.
width = randomInt ()
height = randomInt ()
colour = randomColour () :?> Brush
filePath = saveLocation
overlay = Some (buildFullOverlay ()) }
makeImage spec |> Async.RunSynchronously
fileSaved (spec.width.ToString()) (spec.height.ToString()) = true

15
TestCentre/Script.fsx

@ -0,0 +1,15 @@
// Learn more about F# at http://fsharp.org
// See the 'F# Tutorial' project for more help.
open System.IO
let saveLocation = __SOURCE_DIRECTORY__ + "/SavingTestArea/"
let resetSavingTestArea () =
let files = Directory.GetFileSystemEntries(saveLocation)
match files.Length with
| 0 -> ()
| _ ->
files
|> Array.iter (fun f -> File.Delete(f))
resetSavingTestArea ()

116
TestCentre/TestCentre.fsproj

@ -0,0 +1,116 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\packages\xunit.core.2.4.0\build\xunit.core.props" Condition="Exists('..\packages\xunit.core.2.4.0\build\xunit.core.props')" />
<Import Project="..\packages\xunit.runner.visualstudio.2.4.0\build\net20\xunit.runner.visualstudio.props" Condition="Exists('..\packages\xunit.runner.visualstudio.2.4.0\build\net20\xunit.runner.visualstudio.props')" />
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>9eaee0e6-1e90-4c44-ad22-e8ca727b3392</ProjectGuid>
<OutputType>Library</OutputType>
<RootNamespace>TestCentre</RootNamespace>
<AssemblyName>TestCentre</AssemblyName>
<UseStandardResourceNames>true</UseStandardResourceNames>
<TargetFrameworkVersion>v4.7.1</TargetFrameworkVersion>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Name>TestCentre</Name>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<Tailcalls>false</Tailcalls>
<OutputPath>bin\$(Configuration)\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<WarningLevel>3</WarningLevel>
<DocumentationFile>bin\$(Configuration)\$(AssemblyName).XML</DocumentationFile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<Tailcalls>true</Tailcalls>
<OutputPath>bin\$(Configuration)\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<WarningLevel>3</WarningLevel>
<DocumentationFile>bin\$(Configuration)\$(AssemblyName).XML</DocumentationFile>
</PropertyGroup>
<PropertyGroup>
<MinimumVisualStudioVersion Condition="'$(MinimumVisualStudioVersion)' == ''">11</MinimumVisualStudioVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(FSharpTargetsPath)' == '' AND Exists('$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets') ">
<FSharpTargetsPath>$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets</FSharpTargetsPath>
</PropertyGroup>
<Import Project="$(FSharpTargetsPath)" />
<ItemGroup>
<Compile Include="AssemblyInfo.fs" />
<Compile Include="ConsoleTests.fs" />
<Compile Include="LibraryTests.fs" />
<None Include="Script.fsx" />
<Content Include="packages.config" />
</ItemGroup>
<ItemGroup>
<Reference Include="FsCheck">
<HintPath>..\packages\FsCheck.2.11.0\lib\net452\FsCheck.dll</HintPath>
</Reference>
<Reference Include="FsCheck.Xunit">
<HintPath>..\packages\FsCheck.Xunit.2.11.0\lib\net452\FsCheck.Xunit.dll</HintPath>
</Reference>
<Reference Include="FSharp.Core">
<HintPath>..\packages\FSharp.Core.4.5.2\lib\net45\FSharp.Core.dll</HintPath>
</Reference>
<Reference Include="mscorlib" />
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Drawing" />
<Reference Include="System.Drawing.Common">
<HintPath>..\packages\System.Drawing.Common.4.5.0\lib\net461\System.Drawing.Common.dll</HintPath>
</Reference>
<Reference Include="System.Numerics" />
<Reference Include="System.ValueTuple">
<Private>True</Private>
</Reference>
<Reference Include="xunit.abstractions">
<HintPath>..\packages\xunit.abstractions.2.0.3\lib\net35\xunit.abstractions.dll</HintPath>
</Reference>
<Reference Include="xunit.assert">
<HintPath>..\packages\xunit.assert.2.4.0\lib\netstandard2.0\xunit.assert.dll</HintPath>
</Reference>
<Reference Include="xunit.core">
<HintPath>..\packages\xunit.extensibility.core.2.4.0\lib\net452\xunit.core.dll</HintPath>
</Reference>
<Reference Include="xunit.execution.desktop">
<HintPath>..\packages\xunit.extensibility.execution.2.4.0\lib\net452\xunit.execution.desktop.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\SmoulderingBeachBallCLI\SmoulderingBeachBallCLI.fsproj">
<Name>SmoulderingBeachBallCLI</Name>
<Project>{5c00d583-ef09-4fe6-a3fe-eb01454c0607}</Project>
<Private>True</Private>
</ProjectReference>
<ProjectReference Include="..\SmoulderingBeachBall\SmoulderingBeachBall.fsproj">
<Name>SmoulderingBeachBall</Name>
<Project>{dfc3cbca-3da7-4cf4-a8bc-bccb740fa6cd}</Project>
<Private>True</Private>
</ProjectReference>
</ItemGroup>
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\xunit.runner.visualstudio.2.4.0\build\net20\xunit.runner.visualstudio.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\xunit.runner.visualstudio.2.4.0\build\net20\xunit.runner.visualstudio.props'))" />
<Error Condition="!Exists('..\packages\xunit.core.2.4.0\build\xunit.core.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\xunit.core.2.4.0\build\xunit.core.props'))" />
<Error Condition="!Exists('..\packages\xunit.core.2.4.0\build\xunit.core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\xunit.core.2.4.0\build\xunit.core.targets'))" />
</Target>
<Import Project="..\packages\xunit.core.2.4.0\build\xunit.core.targets" Condition="Exists('..\packages\xunit.core.2.4.0\build\xunit.core.targets')" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

16
TestCentre/packages.config

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="FsCheck" version="2.11.0" targetFramework="net471" />
<package id="FsCheck.Xunit" version="2.11.0" targetFramework="net471" />
<package id="FSharp.Core" version="4.5.2" targetFramework="net471" />
<package id="System.Drawing.Common" version="4.5.0" targetFramework="net471" />
<package id="System.ValueTuple" version="4.5.0" targetFramework="net471" />
<package id="xunit" version="2.4.0" targetFramework="net471" />
<package id="xunit.abstractions" version="2.0.3" targetFramework="net471" />
<package id="xunit.analyzers" version="0.10.0" targetFramework="net471" />
<package id="xunit.assert" version="2.4.0" targetFramework="net471" />
<package id="xunit.core" version="2.4.0" targetFramework="net471" />
<package id="xunit.extensibility.core" version="2.4.0" targetFramework="net471" />
<package id="xunit.extensibility.execution" version="2.4.0" targetFramework="net471" />
<package id="xunit.runner.visualstudio" version="2.4.0" targetFramework="net471" developmentDependency="true" />
</packages>
Loading…
Cancel
Save