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.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.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. *) [] 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 [] 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 [] 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 [] 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 [] let ``Can return a collection of points which represent a grids horizontal lines`` () = let result = determineHorizontalLines (newNum()) (newNum()) (newNum()) result.Length > 0 [] 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 [] 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 [] 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 [] let ``Can return a collection of SKPoints which represent a grids horizontal lines`` () = let result = determineSKHorizontalLines (newNum()) (newNum()) (newNum()) result.Length > 0 [] let ``Can return a collection of SKPoints which represent a grids vertical lines`` () = let result = determineSKVerticalLines (newNum()) (newNum()) (newNum()) result.Length > 0 [] 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 [] 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 [] 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) [] 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) [] 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) [] 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) [] 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) [] 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) [] 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(fun () -> result () |> ignore) [] 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(fun () -> result () |> ignore) [] 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(fun () -> result () |> ignore) [] let ``Can determine image width using SkiaSharp`` () = let dimensions = SkiaSharp (validSkiaImagePath) |> GridPainter.determineImageDimensions let result () = (fst dimensions) = 599 Assert.True (result ()) [] let ``Can determine image height using SkiaSharp`` () = let dimensions = SkiaSharp (validSkiaImagePath) |> GridPainter.determineImageDimensions let result () = (snd dimensions) = 336 Assert.True (result ()) [] let ``Can determine image width using SystemDrawing`` () = let dimensions = SystemDrawing (validSystemDrawingImagePath) |> GridPainter.determineImageDimensions let result () = (fst dimensions) = 338 Assert.True (result ()) [] let ``Can determine image height using SystemDrawing`` () = let dimensions = SystemDrawing (validSystemDrawingImagePath) |> GridPainter.determineImageDimensions let result () = (snd dimensions) = 307 Assert.True (result ()) [] 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(fun () -> result () |> ignore) [] 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(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. *) [] let ``LoadingTestArea contains at least 100 test images`` () = let length = imagesInLoadingTestArea.Length let imagesAreThere = if length < 100 then false else true Assert.True imagesAreThere [] 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 ())) [] 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 ())) [] 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. *) [] let ``SavingTestArea folder can be found`` () = Assert.True (Directory.Exists saveLocation)