Death Socket consists of three projects. They are a .Net Standard 2.0 library, a console program and a Test Centre. The purpose of this repository is to provide a way for people to add grids to images. https://www.craigoates.net/Software/project/13
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

450 lines
18 KiB

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
open DeathSocket.Domain
open SkiaSharp
let rand = Random ()
(* These are duplicates from ConsoleTests.fs (both of them). See point
about helpers. Tests for checking these locations can be found in
ConsoleTests.fs.
Also, these folders should not show up in Visual Studios
Solution Explorer -- unless you are viewing the solution in its folder
format. *)
let loadLocation = __SOURCE_DIRECTORY__ + "/LoadingTestArea"
let saveLocation = __SOURCE_DIRECTORY__ + "/SavingTestArea"
let validSkiaImagePath =
(loadLocation + "/RequiredInfo/Skia-599x336.png")
let validSystemDrawingImagePath =
(loadLocation + "/RequiredInfo/SystemDrawing-338x307.png")
let validImagePath =
(loadLocation + "/RequiredInfo/ImageTest1.png")
let validImagePath2 =
(loadLocation + "/RequiredInfo/ImageTest2.png")
let validImagePath3 =
(loadLocation + "/RequiredInfo/ImageTest3.png")
let invalidImagePath = "invalid.png"
let allColours =
let properties =
typeof<Brushes>.GetProperties
(BindingFlags.Public ||| BindingFlags.Static)
seq { for prop in properties -> prop}
|> Seq.toArray
let randomBrush () =
let item = allColours.[rand.Next(allColours.Length)]
item.GetValue (null, null)
let allSKColours =
let properties =
typeof<SKColors>.GetFields
(BindingFlags.Static ||| BindingFlags.Public)
seq {for prop in properties -> prop}
|> Seq.toArray
let randomSKColour () =
let item = allSKColours.[rand.Next(allSKColours.Length)]
item.GetValue (null) :?> SKColor
(* Max. value is arbitrary (change for performance).
Min. value is to stop divide by zero exceptions.
Intended for horizontal and vertical line tests. *)
let newNum () = rand.Next(1, 1000)
let newPenWidth () = rand.Next (1, 10)
let newRGBANum () = rand.Next (255)
let imagesInLoadingTestArea =
Directory.GetFileSystemEntries (loadLocation, "*.png")
let generateLoadPath () =
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))
let makeTestRGBASpec r g b a =
{ originalPath = "test path"
savePath = "test path"
alpha = float a
red = float r
green = float g
blue = float b
penWidth = float32 10
rows = newNum ()
columns = newNum () }
module PropertyTests =
open System.IO
open System.Drawing
open DeathSocket
open DeathSocket.GridPainter
open TestingHelpers
open FsCheck.Xunit
(* With regards to the "saving images" tests, you should end up with
one image left over in the SavingTestArea folder. 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. *)
[<Property>]
let ``Can apply grid to image and save it using BrushSpec`` () =
resetSavingTestArea ()
let oPath = generateLoadPath ()
let sPath = generateSavePath oPath
Brush ({ originalPath = oPath
savePath = sPath
colour = randomBrush () :?> Brush
penWidth = float32 (newPenWidth())
rows = 10
columns = 10 })
|> applyGridToImageAsync
|> Async.RunSynchronously
(File.Exists sPath) = true
[<Property>]
let ``Can apply grid to image and save it using RGBASpec`` () =
resetSavingTestArea ()
let oPath = generateLoadPath ()
let sPath = generateSavePath oPath
RGBA ({ originalPath = oPath
savePath = sPath
alpha = float (newRGBANum ())
red = float (newRGBANum ())
green = float (newRGBANum ())
blue = float (newRGBANum ())
penWidth = float32 (newPenWidth())
rows = 10
columns = 10 })
|> applyGridToImageAsync
|> Async.RunSynchronously
(File.Exists sPath) = true
[<Property>]
let ``SolidBrush colour matches the individual RGBA values`` () =
let a = newRGBANum ()
let r = newRGBANum ()
let g = newRGBANum ()
let b = newRGBANum ()
let referenceColour = Color.FromArgb (a, r, g, b)
let brush = makeSolidBrushFromRGBA r g b a
brush.Color = referenceColour
[<Property>]
let ``SolidBrush colour matches the RGBASpec`` () =
let a = newRGBANum ()
let r = newRGBANum ()
let g = newRGBANum ()
let b = newRGBANum ()
let referenceColour = Color.FromArgb (a, r, g, b)
let referenceSpec = makeTestRGBASpec r g b a
let brush = makeSolidBrushFromRGBASpec referenceSpec
brush.Color = referenceColour
[<Property>]
let ``Can return a collection of points which represent a grids horizontal lines`` () =
let result = determineHorizontalLines (newNum()) (newNum()) (newNum())
result.Length > 0
[<Property>]
let ``Can return a collection of points which represent a grids vertical lines`` () =
let result = determineVerticalLines (newNum()) (newNum()) (newNum())
result.Length > 0
// This test fails when using SkiaSharp 1.68
[<Property>]
let ``Can apply grid to image and save it using SkiaSpec`` () =
resetSavingTestArea()
let oPath = generateLoadPath ()
let sPath = generateSavePath oPath
Skia ({ originalPath = oPath
savePath= sPath
skColour = randomSKColour ()
penWidth = float32 (newPenWidth())
rows = newNum ()
columns = newNum () })
|> applyGridToImageAsync
|> Async.RunSynchronously
(File.Exists sPath) = true
// This test fails when using SkiaSharp 1.68
[<Property>]
let ``Can apply grid to image and save it using SkiaRGBSpec`` () =
resetSavingTestArea()
let oPath = generateLoadPath ()
let sPath = generateSavePath oPath
SkiaRGB ({ originalPath = oPath
savePath= sPath
red = float32 (newRGBANum ())
green = float32 (newRGBANum ())
blue = float32 (newRGBANum ())
penWidth = float32 (newPenWidth())
rows = newNum ()
columns = newNum () })
|> applyGridToImageAsync
|> Async.RunSynchronously
(File.Exists sPath) = true
[<Property>]
let ``Can return a collection of SKPoints which represent a grids horizontal lines`` () =
let result = determineSKHorizontalLines (newNum()) (newNum()) (newNum())
result.Length > 0
[<Property>]
let ``Can return a collection of SKPoints which represent a grids vertical lines`` () =
let result = determineSKVerticalLines (newNum()) (newNum()) (newNum())
result.Length > 0
[<Property>]
let ``Can create a populated SKData buffer when calling createSKDataAsync with SkiaBuffer`` () =
let result () =
SkiaBuffer ({ filePath = validImagePath
skColour = randomSKColour ()
penWidth = float32 (newPenWidth())
rows = newNum ()
columns = newNum () })
|> createSKDataAsync
|> Async.RunSynchronously
(result ()).IsEmpty = false
[<Property>]
let ``Can create a populated SKData buffer when calling createSKDataAsync with SkiaRGBBuffer`` () =
let result () =
SkiaRGBBuffer ({ filePath = validImagePath3
red = float32 (newNum())
green = float32 (newNum())
blue = float32 (newNum())
penWidth = float32 (newPenWidth())
rows = newNum ()
columns = newNum () })
|> createSKDataAsync
|> Async.RunSynchronously
(result ()).IsEmpty = false
module UnitTests =
open System
open System.IO
open System.Drawing
open Xunit
open DeathSocket
open SkiaSharp
open TestingHelpers
[<Fact>]
let ``An empty SKData object is returned when createSKDataAsync cannot find file when using SkiaBuffer`` () =
let result =
SkiaBuffer ({ filePath = invalidImagePath
penWidth = float32 1
skColour = SKColors.Empty
rows = 1
columns = 1 })
|> GridPainter.createSKDataAsync
|> Async.RunSynchronously
Assert.Equal(SKData.Empty, result)
[<Fact>]
let ``An empty SKData object is returned when createSKDataAsync cannot find file when using SkiaRGBBuffer`` () =
let result =
SkiaRGBBuffer ({ filePath = invalidImagePath
penWidth = float32 1
red = float32 1
green = float32 1
blue = float32 1
rows = 1
columns = 1 })
|> GridPainter.createSKDataAsync
|> Async.RunSynchronously
Assert.Equal(SKData.Empty, result)
[<Fact>]
let ``An empty SKData object is returned when calling createSKDataAsync with SkiaRGB`` () =
let result =
SkiaRGB ({ originalPath = validImagePath2
savePath= validImagePath
red = float32 1
green = float32 1
blue = float32 1
penWidth = float32 1
rows = 1
columns = 1})
|> GridPainter.createSKDataAsync
|> Async.RunSynchronously
Assert.Equal(SKData.Empty, result)
[<Fact>]
let ``An empty SKData object is returned when calling createSKDataAsync with Skia`` () =
let result =
Skia ({ originalPath = validImagePath3
savePath= validImagePath
skColour = SKColors.Empty
penWidth = float32 1
rows = 1
columns = 1 })
|> GridPainter.createSKDataAsync
|> Async.RunSynchronously
Assert.Equal(SKData.Empty, result)
[<Fact>]
let ``An empty SKData object is returned when calling createSKDataAsync with Brush`` () =
let result =
Brush ({ originalPath = validImagePath
savePath= validImagePath
colour = Brushes.AliceBlue
penWidth = float32 1
rows = 1
columns = 1 })
|> GridPainter.createSKDataAsync
|> Async.RunSynchronously
Assert.Equal(SKData.Empty, result)
[<Fact>]
let ``An empty SKData object is returned when calling createSKDataAsync with RGBA`` () =
let result =
RGBA ({ originalPath = validImagePath
savePath= validImagePath
red = float 1
green = float 1
blue = float 1
alpha = float 1
penWidth = float32 1
rows = 1
columns = 1 })
|> GridPainter.createSKDataAsync
|> Async.RunSynchronously
Assert.Equal(SKData.Empty, result)
[<Fact>]
let ``Argument Exception is thrown when actualDimensions are set to 0 when calling scaleLineThickness`` () =
let result () =
GridPainter.scaleLineThickness (1, 0) (0, 0) 1.0
Assert.Throws<ArgumentException>(fun () -> result () |> ignore)
[<Fact>]
let ``Argument Exception is thrown when lineThickness is set to 0 when calling scaleLineThickness`` () =
let result () =
GridPainter.scaleLineThickness (1, 0)(1, 0) 0.0
Assert.Throws<ArgumentException>(fun () -> result () |> ignore)
[<Fact>]
let ``Argument Exception is thrown when previewDimensions are set to 0 when calling scaleLineThickness`` () =
let result () =
GridPainter.scaleLineThickness (0, 0) (1, 0) 1.0
Assert.Throws<ArgumentException>(fun () -> result () |> ignore)
[<Fact>]
let ``Can determine image width using SkiaSharp`` () =
let dimensions =
SkiaSharp (validSkiaImagePath)
|> GridPainter.determineImageDimensions
let result () = (fst dimensions) = 599
Assert.True (result ())
[<Fact>]
let ``Can determine image height using SkiaSharp`` () =
let dimensions =
SkiaSharp (validSkiaImagePath)
|> GridPainter.determineImageDimensions
let result () = (snd dimensions) = 336
Assert.True (result ())
[<Fact>]
let ``Can determine image width using SystemDrawing`` () =
let dimensions =
SystemDrawing (validSystemDrawingImagePath)
|> GridPainter.determineImageDimensions
let result () = (fst dimensions) = 338
Assert.True (result ())
[<Fact>]
let ``Can determine image height using SystemDrawing`` () =
let dimensions =
SystemDrawing (validSystemDrawingImagePath)
|> GridPainter.determineImageDimensions
let result () = (snd dimensions) = 307
Assert.True (result ())
[<Fact>]
let ``Divide By Zero Exception is thrown when 0 rows is used when determining horizontal lines`` () =
let result () = GridPainter.determineHorizontalLines 100 100 0
Assert.Throws<DivideByZeroException>(fun () -> result () |> ignore)
[<Fact>]
let ``Divide By Zero Exception is thrown when 0 columns is used when determining vertical lines`` () =
let result () = GridPainter.determineVerticalLines 100 100 0
Assert.Throws<DivideByZeroException>(fun () -> result () |> ignore)
(* This test is a pre-test test (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 tests 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
[<Fact>]
let ``Pen thickness scales down to match preview image dimensions`` () =
let result () =
GridPainter.scaleLineThickness (100, 100) (200, 200) 10.0
Assert.Equal (5.0, (result ()))
[<Fact>]
let ``Pen thickness scales up to match preview image dimensions`` () =
let result () =
GridPainter.scaleLineThickness (200, 200) (100, 100) 10.0
Assert.Equal (20.0, (result ()))
[<Fact>]
let ``Pen thickness remains the same when preview image matches actual dimensions`` () =
let result () =
GridPainter.scaleLineThickness (100, 100) (100, 100) 10.0
Assert.Equal (10.0, (result ()))
(* This test is a pre-test test. If the property tests fails, here is a
good place to start. The easiest way to get this test to pass is to
create a folder called "SavingTestArea" in this projects folder
(at the root). You can, also, see script.fs (in Test Centre) for
creating this folder via code. (See "LoadingTestArea contains..." note
for extra context. *)
[<Fact>]
let ``SavingTestArea folder can be found`` () =
Assert.True (Directory.Exists saveLocation)