23 changed files with 688 additions and 31 deletions
@ -0,0 +1,23 @@ |
|||||||
|
namespace DeathSocket |
||||||
|
|
||||||
|
[<AutoOpen>] |
||||||
|
module Domain = |
||||||
|
|
||||||
|
open System.Drawing |
||||||
|
open System.Drawing.Imaging |
||||||
|
|
||||||
|
type ImageSpec = |
||||||
|
{ originalPath: string; |
||||||
|
savePath: string; |
||||||
|
colour: Brush; |
||||||
|
penWidth: float32 |
||||||
|
rows: int; |
||||||
|
columns: int } |
||||||
|
|
||||||
|
type StreamSpec = |
||||||
|
{ imagePath: string; |
||||||
|
format: ImageFormat; |
||||||
|
colour: Brush; |
||||||
|
penWidth: float32 |
||||||
|
rows: int; |
||||||
|
columns: int } |
@ -0,0 +1,17 @@ |
|||||||
|
namespace DeathSocket |
||||||
|
|
||||||
|
open System.IO |
||||||
|
|
||||||
|
module GridPainter = |
||||||
|
|
||||||
|
open Validation |
||||||
|
open ImageServices |
||||||
|
|
||||||
|
let applyGrid spec = |
||||||
|
async { |
||||||
|
try |
||||||
|
validateFilePath |> ignore |
||||||
|
drawGrid spec |> ignore |
||||||
|
with |
||||||
|
| :? FileNotFoundException as ex -> printfn "File could not be found at %s" ex.Message |
||||||
|
} |
@ -0,0 +1,31 @@ |
|||||||
|
module internal ImageServices |
||||||
|
|
||||||
|
open System.Drawing |
||||||
|
open System.Drawing.Imaging |
||||||
|
open DeathSocket |
||||||
|
|
||||||
|
let createHorizontalLines width height rows = |
||||||
|
let interval = height / rows |
||||||
|
[| for point in 1 .. (rows - 1) -> |
||||||
|
[|Point (0, (interval * point)) |
||||||
|
Point (width, (interval * point) )|]|] |
||||||
|
|
||||||
|
let createVerticalLines width height columns = |
||||||
|
let interval = width / columns |
||||||
|
[| for point in 1 .. (columns - 1) -> |
||||||
|
[| Point ((interval * point), 0) |
||||||
|
Point ((interval * point), height)|]|] |
||||||
|
|
||||||
|
let drawGrid spec = |
||||||
|
let img = Bitmap.FromFile spec.originalPath |
||||||
|
let graphics = Graphics.FromImage img |
||||||
|
let pen = new Pen (spec.colour, width = spec.penWidth) |
||||||
|
let horizontalLines = |
||||||
|
createHorizontalLines (img.Size.Width) (img.Size.Height) (spec.columns) |
||||||
|
let verticalLines = createVerticalLines (img.Size.Width) (img.Size.Height) (spec.columns) |
||||||
|
for line in horizontalLines do graphics.DrawLines (pen, line) |
||||||
|
for line in verticalLines do graphics.DrawLines (pen, line) |
||||||
|
img.Save (spec.savePath, ImageFormat.Png) |
||||||
|
img.Dispose () |
||||||
|
graphics.Dispose () |
||||||
|
pen.Dispose () |
@ -1,5 +0,0 @@ |
|||||||
namespace DeathSocket |
|
||||||
|
|
||||||
module Say = |
|
||||||
let hello name = |
|
||||||
printfn "Hello %s" name |
|
@ -0,0 +1,42 @@ |
|||||||
|
#load "Domain.fs" |
||||||
|
#load "Validation.fs" |
||||||
|
#load "ImageServices.fs" |
||||||
|
#load "GridPainter.fs" |
||||||
|
|
||||||
|
open System.Drawing |
||||||
|
open System |
||||||
|
open DeathSocket |
||||||
|
open Validation |
||||||
|
open ImageServices |
||||||
|
|
||||||
|
(* Death Socket Scripts |
||||||
|
=============================================================================== |
||||||
|
The code in here can be use to create a gridded image without running the CLI. |
||||||
|
You can, also, run checks to see what Death Socket is doing when creating |
||||||
|
a nerw image. *) |
||||||
|
|
||||||
|
let desktop = Environment.GetFolderPath (Environment.SpecialFolder.Desktop) |
||||||
|
|
||||||
|
(* You will need to provide the image at the location specified. It will throw |
||||||
|
an exception if the file cannnot be found.*) |
||||||
|
let validationTest = validateFilePath (desktop + "/test.jpg") |
||||||
|
|
||||||
|
(* These are not needed to create an image. There here for you to check the |
||||||
|
start and end points of each pen stroke/path. *) |
||||||
|
let horizontalLines = createHorizontalLines 1000 500 10 |
||||||
|
let verticalLines = createVerticalLines 300 600 10 |
||||||
|
|
||||||
|
(* You will need to provide the image and specify its load/save location. |
||||||
|
Death Socket assumes either JPEG or PNG files so use other files at your own |
||||||
|
risk. Cannot guarantee they will work. Also, either in this spec. can be |
||||||
|
changed to suit your needs. *) |
||||||
|
let spec = |
||||||
|
{ originalPath = desktop + "/test.jpg" |
||||||
|
savePath = desktop + "/grid.png" |
||||||
|
colour = Brushes.Chartreuse |
||||||
|
penWidth = (float32 1) |
||||||
|
rows = 10 |
||||||
|
columns = 10 } |
||||||
|
|
||||||
|
// Run this when you have finished building the spec. |
||||||
|
GridPainter.applyGrid spec |> Async.RunSynchronously |
@ -0,0 +1,9 @@ |
|||||||
|
module internal Validation |
||||||
|
|
||||||
|
open System.IO |
||||||
|
|
||||||
|
let validateFilePath path = |
||||||
|
match File.Exists path with |
||||||
|
| true -> () |
||||||
|
| false -> raise (new FileNotFoundException (path + " could not be found.")) |
||||||
|
|
@ -0,0 +1,93 @@ |
|||||||
|
namespace Commands |
||||||
|
|
||||||
|
module ConsoleCommands = |
||||||
|
open System |
||||||
|
open DeathSocket.GridPainter |
||||||
|
open DeathSocketCLI.Validation |
||||||
|
open System.IO |
||||||
|
open Console.Waterworks |
||||||
|
open Console.Waterworks.Attributes |
||||||
|
|
||||||
|
let showEndOfCommandMessage = "[INFO.] Task completed." |
||||||
|
|
||||||
|
[<ListCommand>] |
||||||
|
[<Parameters "none">] |
||||||
|
[<Description |
||||||
|
"Display a text message indicating this program is running properly.">] |
||||||
|
[<Usage "test">] |
||||||
|
let test () = "[SUCCESS] Death Socket is working." |
||||||
|
|
||||||
|
[<ListCommand>] |
||||||
|
[<Parameters "none">] |
||||||
|
[<Description "Displays a list of available commands provided by this program.">] |
||||||
|
[<Usage "help">] |
||||||
|
let help () = CW_Liaison().RequestHelpDocumentation("Commands") |
||||||
|
|
||||||
|
[<ListCommand>] |
||||||
|
[<Parameters "none">] |
||||||
|
[<Description "Exits out of the program.">] |
||||||
|
[<Usage "exit">] |
||||||
|
let exit () = Environment.Exit (Environment.ExitCode) |
||||||
|
|
||||||
|
[<ListCommand>] |
||||||
|
[<Parameters "(image-path: string) (new-path: string)">] |
||||||
|
[<Description |
||||||
|
"Takes the image at 'image-path' applies a 10x10 grid (in white) to it and saves the result at 'new-path'.">] |
||||||
|
[<Usage "add-default C:/base-image.png C:/final-image.png">] |
||||||
|
let ``add-default`` imgPath newPath = |
||||||
|
try |
||||||
|
printfn "[INFO.] Adding default grid to image..." |
||||||
|
buildDefaultSpec imgPath newPath |
||||||
|
|> applyGrid |
||||||
|
|> Async.RunSynchronously |
||||||
|
showEndOfCommandMessage |
||||||
|
with |
||||||
|
| :? FileNotFoundException as ex -> "[ERROR] No file was found at " + ex.FileName |
||||||
|
| :? ArgumentException as ex -> "[ERROR] Invalid argument: " + ex.Message |
||||||
|
| _ as ex -> ex.Message |
||||||
|
|
||||||
|
[<ListCommand>] |
||||||
|
[<Parameters |
||||||
|
("(image-path: string) (no-of-rows: int) (no-of-columns: int) " + |
||||||
|
"(pen-width: float32) (colour: string) (new-path: string)")>] |
||||||
|
[<Description "Adds a grid to an image, using the specified parameters, and saves it.">] |
||||||
|
[<Usage |
||||||
|
"add-grid C:/orignal-image.png 10 5 2 red C:/new-image.png">] |
||||||
|
let ``add-grid`` imgPath numRows numColumns pWidth colour newPath = |
||||||
|
try |
||||||
|
printfn "[INFO.] Adding grid to image..." |
||||||
|
buildSpec imgPath numRows numColumns pWidth colour newPath |
||||||
|
|> applyGrid |
||||||
|
|> Async.RunSynchronously |
||||||
|
showEndOfCommandMessage |
||||||
|
with |
||||||
|
| :? FileNotFoundException as ex -> "[ERROR] No file was found at " + ex.FileName |
||||||
|
| :? ArgumentException as ex -> "[ERROR] Invalid argument: " + ex.Message |
||||||
|
| _ as ex -> ex.Message |
||||||
|
|
||||||
|
[<ListCommand>] |
||||||
|
[<Parameters "none">] |
||||||
|
[<Description |
||||||
|
"Lists out the colours this program uses to draw its grids.">] |
||||||
|
[<Usage "list-colours">] |
||||||
|
let ``list-colours`` () = |
||||||
|
printfn "[INFO.] Listing available colours..." |
||||||
|
for item in colourList do |
||||||
|
printfn "%s" item.Key |
||||||
|
showEndOfCommandMessage |
||||||
|
|
||||||
|
(* ALIASES |
||||||
|
======================================================================= |
||||||
|
These command-methods will not show up in the help section. Before |
||||||
|
adding extra aliases, make sure the main version is as clear and |
||||||
|
helpful to someone new to the program as possible. Aliases should be |
||||||
|
treated as commands for experienced users and documented on the wiki, |
||||||
|
hosted alongside the repository on GitHub. |
||||||
|
URL: https://github.com/CraigOates/Death-Socket/wiki *) |
||||||
|
|
||||||
|
let ad imgPath newPath = ``add-default`` imgPath newPath |
||||||
|
|
||||||
|
let ag imgPath numRows numColumns pWidth colour newPath = |
||||||
|
``add-grid`` imgPath numRows numColumns pWidth colour newPath |
||||||
|
|
||||||
|
let lc () =``list-colours`` () |
@ -1,7 +1,7 @@ |
|||||||
// Learn more about F# at http://fsharp.org |
open Console.Waterworks |
||||||
// See the 'F# Tutorial' project for more help. |
|
||||||
|
|
||||||
[<EntryPoint>] |
[<EntryPoint>] |
||||||
let main argv = |
let main argv = |
||||||
printfn "%A" argv |
let liaison = CW_Liaison () |
||||||
0 // return an integer exit code |
liaison.Run ("Commands", true) |
||||||
|
0 |
||||||
|
@ -0,0 +1,62 @@ |
|||||||
|
module DeathSocketCLI.Validation |
||||||
|
|
||||||
|
open DeathSocket |
||||||
|
open System.Drawing |
||||||
|
open System |
||||||
|
open System.IO |
||||||
|
|
||||||
|
let colourList = |
||||||
|
[ "blue", Brushes.AliceBlue |
||||||
|
"brown", Brushes.Brown |
||||||
|
"black", Brushes.Black |
||||||
|
"gray", Brushes.Gray |
||||||
|
"grey", Brushes.Gray |
||||||
|
"green", Brushes.Green |
||||||
|
"purple", Brushes.Purple |
||||||
|
"red", Brushes.Red |
||||||
|
"white", Brushes.White |
||||||
|
"yellow", Brushes.Yellow ] |
||||||
|
|> Map.ofList |
||||||
|
|
||||||
|
let isColourValid (colour: string) = |
||||||
|
colourList |
||||||
|
|> Map.containsKey (colour.ToLower()) |
||||||
|
|
||||||
|
let parseColour colour = |
||||||
|
match (isColourValid colour) with |
||||||
|
| true -> |
||||||
|
colourList |
||||||
|
|> Map.find (colour.ToLower()) |
||||||
|
| false -> |
||||||
|
invalidArg "Colour" |
||||||
|
(String.Concat("The colour specifed is invalid.\n", |
||||||
|
"Please use the 'list-colours' command to see what you can use.")) |
||||||
|
|
||||||
|
let setPenWidth imgWidth imgHeight = |
||||||
|
let width = float32 imgWidth |
||||||
|
let height = float32 imgHeight |
||||||
|
if (width >= height) then |
||||||
|
height * (float32 0.002) |
||||||
|
else width * (float32 0.002) |
||||||
|
|
||||||
|
let buildSpec imgPath numRows numColumns pWidth colour newPath = |
||||||
|
{ originalPath = imgPath |
||||||
|
savePath = newPath |
||||||
|
colour = parseColour colour |
||||||
|
penWidth = pWidth |
||||||
|
rows = numRows |
||||||
|
columns = numColumns } |
||||||
|
|
||||||
|
let buildDefaultSpec imgPath newPath = |
||||||
|
let stream = new FileStream (imgPath, FileMode.Open) |
||||||
|
let image = Image.FromStream (stream, false, false) |
||||||
|
let spec = |
||||||
|
{ originalPath = imgPath |
||||||
|
savePath = newPath |
||||||
|
colour = Brushes.White |
||||||
|
penWidth = setPenWidth (image.Width) (image.Height) |
||||||
|
rows = 10 |
||||||
|
columns = 10 } |
||||||
|
stream.Dispose () |
||||||
|
image.Dispose () |
||||||
|
spec |
After Width: | Height: | Size: 81 KiB |
@ -1,5 +1,7 @@ |
|||||||
<?xml version="1.0" encoding="utf-8"?> |
<?xml version="1.0" encoding="utf-8"?> |
||||||
<packages> |
<packages> |
||||||
|
<package id="Console.Waterworks" version="0.1.0.0-alpha1" targetFramework="net471" /> |
||||||
<package id="FSharp.Core" version="4.5.2" targetFramework="net471" /> |
<package id="FSharp.Core" version="4.5.2" targetFramework="net471" /> |
||||||
<package id="System.ValueTuple" version="4.4.0" targetFramework="net471" /> |
<package id="System.Drawing.Common" version="4.5.0" targetFramework="net471" /> |
||||||
|
<package id="System.ValueTuple" version="4.5.0" targetFramework="net471" /> |
||||||
</packages> |
</packages> |
Binary file not shown.
@ -0,0 +1,113 @@ |
|||||||
|
namespace ConsoleTests |
||||||
|
|
||||||
|
(* Initial Setup -- Populating the Test Folders. |
||||||
|
=========================================================================== |
||||||
|
If you have just cloned this repository or have not run any of the tests |
||||||
|
before, please head over to script.fs (in Test Centre) and populate the |
||||||
|
LoadingTestArea and SavingTestArea folders. More information will be |
||||||
|
provided there about what the scripts do. It is worth pointing out here the |
||||||
|
.gitignore file ignores any .png files in them. This is why you must |
||||||
|
populate them before running any tests. *) |
||||||
|
|
||||||
|
module TestingHelpers = |
||||||
|
|
||||||
|
(* When you are writing tests, please keep all helper functions in this |
||||||
|
module. If this module grows to a point where it hinders the actual |
||||||
|
testing modules, consider moving it then. If you do decide to move them |
||||||
|
out, pay attention to LibraryTests.fs and its helper functions. *) |
||||||
|
|
||||||
|
open System |
||||||
|
open DeathSocketCLI.Validation |
||||||
|
|
||||||
|
// Directory Path |
||||||
|
let saveLocation = __SOURCE_DIRECTORY__ + "/SavingTestArea" |
||||||
|
let loadLocation = __SOURCE_DIRECTORY__ + "/LoadingTestArea" |
||||||
|
|
||||||
|
// File Path |
||||||
|
let loadPath = loadLocation + "/RequiredInfo/LoadTest.png" |
||||||
|
let savePath = saveLocation + "/SaveTest.png" |
||||||
|
|
||||||
|
(* Brushes converted to string []. |
||||||
|
CLI deals with strings before brushes. *) |
||||||
|
let testingColourArray = |
||||||
|
colourList |
||||||
|
|> Map.toSeq |
||||||
|
|> Seq.map fst |
||||||
|
|> Seq.toArray |
||||||
|
|
||||||
|
let randomColourString () = |
||||||
|
testingColourArray.[Random().Next(testingColourArray.Length - 1)] |
||||||
|
|
||||||
|
let randomBrush () = |
||||||
|
colourList |
||||||
|
|> Map.toSeq |
||||||
|
|> Seq.map snd |
||||||
|
|> Seq.toArray |
||||||
|
|> Array.item (Random().Next(colourList.Count)) |
||||||
|
|
||||||
|
module PropertyTests = |
||||||
|
|
||||||
|
open System |
||||||
|
open FsCheck.Xunit |
||||||
|
open DeathSocketCLI.Validation |
||||||
|
open System.Drawing |
||||||
|
open TestingHelpers |
||||||
|
open DeathSocket.Domain |
||||||
|
|
||||||
|
[<Property>] |
||||||
|
let ``Pen width is set greater than 0`` () = |
||||||
|
(setPenWidth (Random().Next()) (Random().Next())) > 0.0f |
||||||
|
|
||||||
|
[<Property>] |
||||||
|
let ``Can build the intended default image specification`` () = |
||||||
|
let defaultSpec = |
||||||
|
{ originalPath = loadPath |
||||||
|
savePath = savePath |
||||||
|
colour = Brushes.White |
||||||
|
penWidth = setPenWidth 1000 1000 |
||||||
|
rows = 10 |
||||||
|
columns = 10 } |
||||||
|
let spec = buildDefaultSpec loadPath savePath |
||||||
|
defaultSpec = spec |
||||||
|
|
||||||
|
[<Property>] |
||||||
|
let ``Can build an image specification as intended`` () = |
||||||
|
let colourString = randomColourString () |
||||||
|
let brush = parseColour colourString |
||||||
|
let pWidth = float32 (Random().Next()) |
||||||
|
let randRows = Random().Next() |
||||||
|
let randCols = Random().Next() |
||||||
|
let intendedSpec = |
||||||
|
{ originalPath = loadPath |
||||||
|
savePath = savePath |
||||||
|
colour = brush |
||||||
|
penWidth = pWidth |
||||||
|
rows =randRows |
||||||
|
columns = randCols } |
||||||
|
let spec = |
||||||
|
buildSpec loadPath randRows randCols pWidth colourString savePath |
||||||
|
intendedSpec = spec |
||||||
|
|
||||||
|
module UnitTests = |
||||||
|
|
||||||
|
open System.IO |
||||||
|
open DeathSocketCLI.Validation |
||||||
|
open Xunit |
||||||
|
open TestingHelpers |
||||||
|
|
||||||
|
[<Fact>] |
||||||
|
let ``Saving Test Area can be located`` () = |
||||||
|
Assert.True (Directory.Exists saveLocation) |
||||||
|
|
||||||
|
[<Fact>] |
||||||
|
let ``Loading Test Area can be located`` () = |
||||||
|
Assert.True (Directory.Exists loadLocation) |
||||||
|
|
||||||
|
[<Fact>] |
||||||
|
let ``Colour list is not empty`` () = |
||||||
|
Assert.False (colourList.IsEmpty) |
||||||
|
|
||||||
|
[<Fact>] |
||||||
|
let ``Exception thrown when invalid colour is used`` () = |
||||||
|
Assert.Throws<System.ArgumentException> |
||||||
|
(fun () -> parseColour "not a valid colour" |> ignore) |
@ -1,4 +0,0 @@ |
|||||||
namespace TestCentre |
|
||||||
|
|
||||||
type Class1() = |
|
||||||
member this.X = "F#" |
|
@ -0,0 +1,106 @@ |
|||||||
|
namespace LibraryTests |
||||||
|
|
||||||
|
(* Initial Setup -- Populating the Test Folders. |
||||||
|
=========================================================================== |
||||||
|
If you have just cloned this repository or have not run any of the tests |
||||||
|
before, please head over to script.fs (in Test Centre) and populate the |
||||||
|
LoadingTestArea and SavingTestArea folders. More information will be |
||||||
|
provided there about what the scripts do. It is worth pointing out here the |
||||||
|
.gitignore file ignores any .png files in them. This is why you must |
||||||
|
populate them before running any tests. *) |
||||||
|
|
||||||
|
module TestingHelpers = |
||||||
|
|
||||||
|
(* When you are writing tests, please keep all helper functions in this |
||||||
|
module. If this module grows to a point where it hinders the actual |
||||||
|
testing modules, consider moving it then. If you do decide to move them |
||||||
|
out, pay attention to ConsoleTests.fs and its helper functions. *) |
||||||
|
|
||||||
|
open System |
||||||
|
open System.Drawing |
||||||
|
open System.Reflection |
||||||
|
open System.IO |
||||||
|
|
||||||
|
(* These are duplicates from ConsoleTests.fs (both of them). See point |
||||||
|
about helpers. Tests for checking these locations can be found in |
||||||
|
ConsoleTests.fs.*) |
||||||
|
let loadLocation = __SOURCE_DIRECTORY__ + "/LoadingTestArea" |
||||||
|
let saveLocation = __SOURCE_DIRECTORY__ + "/SavingTestArea" |
||||||
|
|
||||||
|
let allColours = |
||||||
|
let properties = |
||||||
|
typeof<Brushes>.GetProperties |
||||||
|
(BindingFlags.Public ||| BindingFlags.Static) |
||||||
|
seq { for prop in properties -> prop} |
||||||
|
|> Seq.toArray |
||||||
|
|
||||||
|
let randomBrush () = |
||||||
|
let item = allColours.[Random().Next(allColours.Length)] |
||||||
|
item.GetValue(null, null) |
||||||
|
|
||||||
|
let imagesInLoadingTestArea = |
||||||
|
Directory.GetFileSystemEntries (loadLocation, "*.png") |
||||||
|
|
||||||
|
let generateLoadPath () = |
||||||
|
let rand = Random () |
||||||
|
let files = imagesInLoadingTestArea |
||||||
|
files.[rand.Next(files.Length)] |
||||||
|
|
||||||
|
let generateSavePath originalFilePath = |
||||||
|
let fileName = Path.GetFileName originalFilePath |
||||||
|
saveLocation + "/" + fileName |
||||||
|
|
||||||
|
(* To "manually" clear out the SavingTestArea folder, use this function |
||||||
|
in script.fsx. More information can be found there, also.*) |
||||||
|
let resetSavingTestArea () = |
||||||
|
let files = Directory.GetFileSystemEntries(saveLocation, "*.png") |
||||||
|
match files.Length with |
||||||
|
| 0 -> () |
||||||
|
| _ -> |
||||||
|
files |
||||||
|
|> Array.iter (fun f -> File.Delete(f)) |
||||||
|
|
||||||
|
module PropertyTests = |
||||||
|
|
||||||
|
open FsCheck.Xunit |
||||||
|
open DeathSocket |
||||||
|
open System.Drawing |
||||||
|
open DeathSocket.GridPainter |
||||||
|
open TestingHelpers |
||||||
|
open System.IO |
||||||
|
|
||||||
|
[<Property>] |
||||||
|
let ``Can apply grid to image and save it`` () = |
||||||
|
(* You should end up with one image left over in SavingTestArea. |
||||||
|
Comment out the "reset" function to see all the images produced, |
||||||
|
by this test. This will mean you will need to manually delete the |
||||||
|
images yourself if you do.*) |
||||||
|
resetSavingTestArea () |
||||||
|
let oPath = generateLoadPath () |
||||||
|
let sPath = generateSavePath oPath |
||||||
|
let spec = |
||||||
|
{ originalPath = oPath |
||||||
|
savePath = sPath |
||||||
|
colour = randomBrush () :?> Brush |
||||||
|
penWidth = float32 1 |
||||||
|
rows = 10 |
||||||
|
columns = 10 } |
||||||
|
applyGrid spec |
||||||
|
|> Async.RunSynchronously |
||||||
|
(File.Exists sPath) = true |
||||||
|
|
||||||
|
module UnitTests = |
||||||
|
|
||||||
|
open TestingHelpers |
||||||
|
open Xunit |
||||||
|
|
||||||
|
(* This test is a precaution (a test for the tests if you will...). |
||||||
|
It is here to make sure the property test has what it needs to run. |
||||||
|
If the property test fails, here is a good place to start. |
||||||
|
See script.fs (in Test Centre) for information on populating the |
||||||
|
LoadingTestArea folder. *) |
||||||
|
[<Fact>] |
||||||
|
let ``LoadingTestArea contains at least 100 test images`` () = |
||||||
|
let length = imagesInLoadingTestArea.Length |
||||||
|
let imagesAreThere = if length < 100 then false else true |
||||||
|
Assert.True imagesAreThere |
After Width: | Height: | Size: 22 KiB |
@ -1,8 +1,96 @@ |
|||||||
// Learn more about F# at http://fsharp.org |
// These DLL's must be built before you can use them in this script. |
||||||
// See the 'F# Tutorial' project for more help. |
#r "bin/Debug/System.Drawing.Common.dll" |
||||||
|
#r "bin/Debug/SmoulderingBeachBall.dll" |
||||||
|
|
||||||
#load "Library1.fs" |
open System |
||||||
open TestCentre |
open System.Drawing |
||||||
|
open System.Reflection |
||||||
|
open SmoulderingBeachBall.Domain |
||||||
|
open SmoulderingBeachBall.Services |
||||||
|
open System.Threading |
||||||
|
open System.IO |
||||||
|
|
||||||
// Define your library scripting code here |
let loadLocation = __SOURCE_DIRECTORY__ + "/LoadingTestArea" |
||||||
|
let saveLocation = __SOURCE_DIRECTORY__ + "/SavingTestArea" |
||||||
|
let random = Random() |
||||||
|
|
||||||
|
(*Resetting the Testing Area Folders Scripts |
||||||
|
=============================================================================== |
||||||
|
The following scripts are for when you need to "manually" clear out the |
||||||
|
LoadingTestArea and SavingTestArea folders. If you do not want to open up the |
||||||
|
folder in Explorer and delete the files that way, just run the scripts in this |
||||||
|
section. If you reset the LoadingTestArea, you will need to repopulate it using |
||||||
|
the "Populating LoadingTestArea Folder Scripts" below. *) |
||||||
|
|
||||||
|
let resetSavingTestArea () = |
||||||
|
let files = Directory.GetFileSystemEntries(saveLocation, "*.png") |
||||||
|
match files.Length with |
||||||
|
| 0 -> () |
||||||
|
| _ -> |
||||||
|
files |
||||||
|
|> Array.iter (fun f -> File.Delete(f)) |
||||||
|
|
||||||
|
let resetLoadingTestArea () = |
||||||
|
let files = Directory.GetFileSystemEntries(loadLocation, "*.png") |
||||||
|
match files.Length with |
||||||
|
| 0 -> () |
||||||
|
| _ -> |
||||||
|
files |
||||||
|
|> Array.iter (fun f -> File.Delete(f)) |
||||||
|
|
||||||
|
// Run these when the above functions have been added to F# interactive. |
||||||
|
resetSavingTestArea () |
||||||
|
resetLoadingTestArea () |
||||||
|
|
||||||
|
(* Populating LoadingTestArea Folder Scripts |
||||||
|
=============================================================================== |
||||||
|
The following scripts are to help you populate a test folder of images. |
||||||
|
You can then use these images in LibraryTests.fs -- Property Tests. |
||||||
|
The tests consists of loading images from LoadingTestArea, transforming them |
||||||
|
and saving them in SavingTestArea. *) |
||||||
|
|
||||||
|
let allColours = |
||||||
|
let properties = |
||||||
|
typeof<Brushes>.GetProperties(BindingFlags.Public ||| BindingFlags.Static) |
||||||
|
seq { for prop in properties -> prop} |
||||||
|
|> Seq.toArray |
||||||
|
|
||||||
|
let randomBrush () = |
||||||
|
let item = allColours.[random.Next(allColours.Length)] |
||||||
|
item.GetValue(null, null) |
||||||
|
|
||||||
|
let generateDimensionSizes total = |
||||||
|
List.init total (fun _ -> random.Next(3000)) |
||||||
|
|
||||||
|
let randomSize (sizes: int list) = |
||||||
|
// (Sleep) Helps to reduce chance of picking the same item twice in quick succession. |
||||||
|
Thread.Sleep 100 |
||||||
|
sizes.Item (random.Next(sizes.Length)) |
||||||
|
|
||||||
|
let populateSpec sizes = |
||||||
|
{ width = randomSize (sizes) |
||||||
|
height = randomSize (sizes) |
||||||
|
colour = (randomBrush ()) :?> Brush |
||||||
|
filePath = loadLocation |
||||||
|
overlay = None } |
||||||
|
|
||||||
|
let generateSpecs amount = |
||||||
|
let imageSizes = generateDimensionSizes amount |
||||||
|
[for i in 0 .. amount -> (populateSpec (imageSizes)) ] |
||||||
|
|
||||||
|
let generateImage spec = |
||||||
|
printfn "[INFO.] Creating image [Width: %i] [Height: %i] ..." (spec.width) (spec.height) |
||||||
|
makeImage spec |
||||||
|
|
||||||
|
let populateLoadingTestArea () = |
||||||
|
printfn "[INFO.] Populating LoadingTestArea..." |
||||||
|
generateSpecs 100 |
||||||
|
|> List.map generateImage |
||||||
|
|> Async.Parallel |
||||||
|
|> Async.RunSynchronously |
||||||
|
|> ignore |
||||||
|
printfn "[INFO.] Finishing populating /LoadingTestArea." |
||||||
|
|
||||||
|
// You should only need this once. |
||||||
|
// Make sure you have passed the above into F# Interactive. |
||||||
|
populateLoadingTestArea () |
@ -1,5 +1,17 @@ |
|||||||
<?xml version="1.0" encoding="utf-8"?> |
<?xml version="1.0" encoding="utf-8"?> |
||||||
<packages> |
<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="FSharp.Core" version="4.5.2" targetFramework="net471" /> |
||||||
<package id="System.ValueTuple" version="4.4.0" targetFramework="net471" /> |
<package id="SmoulderingBeachBall" version="0.4.0-alpha1" 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> |
</packages> |
Loading…
Reference in new issue