diff --git a/.github/Images/cli-generating-text.png b/.github/Images/cli-generating-text.png new file mode 100644 index 0000000..dfd7ef5 Binary files /dev/null and b/.github/Images/cli-generating-text.png differ diff --git a/.github/Images/generate-random-text-example.png b/.github/Images/generate-random-text-example.png new file mode 100644 index 0000000..a710ca6 Binary files /dev/null and b/.github/Images/generate-random-text-example.png differ diff --git a/.github/Images/solution-structure.png b/.github/Images/solution-structure.png new file mode 100644 index 0000000..5a660a9 Binary files /dev/null and b/.github/Images/solution-structure.png differ diff --git a/.github/Images/test-explorer-example.png b/.github/Images/test-explorer-example.png new file mode 100644 index 0000000..ffa3aa8 Binary files /dev/null and b/.github/Images/test-explorer-example.png differ diff --git a/.github/Images/wet-pancake-banner.png b/.github/Images/wet-pancake-banner.png new file mode 100644 index 0000000..4bd5c81 Binary files /dev/null and b/.github/Images/wet-pancake-banner.png differ diff --git a/.github/Images/wet-pancake-feed-logo.png b/.github/Images/wet-pancake-feed-logo.png new file mode 100644 index 0000000..22a2741 Binary files /dev/null and b/.github/Images/wet-pancake-feed-logo.png differ diff --git a/README.md b/README.md index 2eb9abf..b47a1e5 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,91 @@ -# Wet-Pancake -A test project to see how well Console.Waterworks based console programs work with F# libraries. Wet Pancake generates text using the world famous Markov chain. +![Wet Pancake Banner](.github/Images/wet-pancake-banner.png) + +**Note: This project is a work in-progress. Doc's might be out-of-date** + +# Summary + +Wet Pancake is a NuGet package which generates random text. The solution, also, has a console program for those not needing to program against the package. + +## Pre-Requisites + +- Visual Studio 2017 +- F# +- C# +- XUnit +- FsCheck +- Console.Waterworks +- .Net 4.7 + +### Disclaimer + +This project started out as a test project. It was not my intention for it to grow to what it is now (granted, it is still not massive.) At first, I wanted to see how well the [Console.Waterworks](https://github.com/CraigOates/Console.Waterworks) NuGet package worked with F# libraries. This meant I needed to learn F#. To do this, I used [FsMarkov](https://blog.taylorwood.io/2015/07/04/markov-text.html) as a reference/goal to work towards. Because of these factors, the codebase has taken the shape it has. It did not start off with the best development practices. And, the fact, it is now a [NuGet](https://www.nuget.org/profiles/Craig.Oates) package, is a goal which came somewhat after the initial playing period. So, if you find yourself wanting to scream at me for glaring and obvious mistakes, please be kind. Thanks. + +![Image of the CLI generating text](.github/Images/cli-generating-text.png) + +## Wet Pancake: Solution + +The solution consists of three projects. They are WetPancake (NuGet package), WetPancakeCLI and TestCentre. + +![Image of the solution's structure](.github/Images/solution-structure.png) + +### Wet Pancake (Library/NuGet Package) + +This is a F# library project, using .Net 4.7. You can install this package from two places: + +1. [**MyGet:**](https://myget.org/gallery/the-immutable-null) This is the testbed for my NuGet packages before they make there way over to nuget.org. The packages here are less stable but they are where you will find the latest bits to test out. If you are unsure how to subscribe to a MyGet feed, click [here](http://docs.myget.org/docs/walkthrough/getting-started-with-nuget). +2. [**NuGet:**](https://www.nuget.org/profiles/Craig.Oates) This is the official host for NuGets. Download Wet Pancake from this feed for the most stable releases. + +You can add Wet Pancake to your project via the following commands: + +``` powershell +// Using the built-in Package Manager console in Visual Studio. +// Also, remove "< >" when inserting the package version. + +// MyGet + +PM> Install-Package WetPancake -Version -Source https://www.myget.org/F/the-immutable-null/api/v3/index.json + +// NuGet + +PM> Install-Package Wet-Pancake -Version +``` + +For further information about this project, please visit the [wiki](https://github.com/CraigOates/Wet-Pancake/wiki). + +### Wet Pancake CLI + +This project is a C# console program, using .Net 4.7. You use it by entering commands and awaiting the result. It uses [Console.Waterworks](https://github.com/CraigOates/Console.Waterworks) to parse the commands so, if you want to extend it, I recommend you read its [wiki](https://github.com/CraigOates/Console.Waterworks/wiki). If you want to get going straight away, I recommend using *GenerateRandomText*. For more commands, you can either type *Help* into the console or visit the [wiki](https://github.com/CraigOates/Wet-Pancake/wiki). + +![Image of the GenerateRandomText in use](.github/Images/generate-random-text-example.png) + +### Test Centre + +This project holds all the tests for this solution. If uses a combination of unit tests ([XUnit](http://xunit.github.io/)) and property tests ([FsCheck](https://fscheck.github.io/FsCheck/)). If you are unfamiliar with either of them, click on their links for more information. Also, all the tests are accessible in Visual Studio's Test Explorer. This means you can identify failing tests with ease. + +![Image of VS's Test Explorer](.github/Images/test-explorer-example.png) + +## How to Contribute + +If you would like to contribute to the project, first of all, thank you and here are some useful links for for you to get started. + +- [Contribution page](https://github.com/CraigOates/Wet-Pancake/blob/master/CONTRIBUTING.md) +- [Issues](https://github.com/CraigOates/Wet-Pancake/issues) +- [Bug Report Template](https://github.com/CraigOates/Wet-Pancake/blob/master/.github/ISSUE_TEMPLATE/bug_report.md) +- [Feature Request Template](https://github.com/CraigOates/Wet-Pancake/blob/master/.github/ISSUE_TEMPLATE/feature_request.md) +- [Pull Request Template](https://github.com/CraigOates/Wet-Pancake/blob/master/PULL_REQUEST_TEMPLATE.md) +- [Custom Template](https://github.com/CraigOates/Wet-Pancake/blob/master/.github/ISSUE_TEMPLATE/custom.md) + +## Code of Conduction + +Please visit the Code of Conduct page for Wet Pancake at: + +- [Code of Conduct page](https://github.com/CraigOates/Wet-Pancake/blob/master/CODE_OF_CONDUCT.md) +- [MIT License](https://github.com/CraigOates/Wet-Pancake/blob/master/LICENSE) + +## About the Creator + +Hi, my name is Craig and I am the creator of Wet Pancake. Thanks for checking it out. + +- Email: [craig@craigoates.net](http://www.craig@craigoates.net) +- Web: [http://www.craigaotes.net](http://www.craigaotes.net) +- Project: [http://www.craigoates.net/Software/project/12](http://www.craigoates.net/Software/project/12) \ No newline at end of file diff --git a/TestCentre/PropertyTests.fs b/TestCentre/PropertyTests.fs index dd790f6..68d2fe1 100644 --- a/TestCentre/PropertyTests.fs +++ b/TestCentre/PropertyTests.fs @@ -9,87 +9,6 @@ open Helpers open InputGeneration - (* Note: Do the null tests need to remain? - =============================================================================================================== - These tests do not test anything beyond the unit tests. - Considering deleting the null tests... - =============================================================================================================== - module ``Null Tests`` = - - [] - let ``Request Random Text does not return a null when using the built-in random settings`` () = - let test = - Pancake.RequestRandomTextAsync () - |> Async.RunSynchronously - let results = Assert.NotNull test - Check.Quick results - - [] - let ``Request Text does not return a null when using fixed input parameters`` () = - // Change the values for a quick way to manually test the (test) code. - let test ()= - Pancake.RequestTextAsync 5 5 - |> Async.RunSynchronously - let results = Assert.NotNull (test()) - Check.Quick results - - [] - let ``Request Text does not return a null when using a random gibberish level`` () = - let test ()= - Pancake.RequestTextAsync (ValidGibberishLevelInput()) 5 - |> Async.RunSynchronously - let results = Assert.NotNull (test()) - Check.Quick results - - [] - let ``Request Text does not return a null when using a random sentence count`` () = - let test () = - Pancake.RequestTextAsync 5 (ValidSentencesInput()) - |> Async.RunSynchronously - let results = Assert.NotNull test - Check.Quick results - - [] - let ``RequestTextFromFile does not return a null when using console-waterworks-info`` () = - let test () = - Pancake.RequestTextFromFileAsync (ValidGibberishLevelInput()) (ValidSentencesInput()) ConsoleWaterworks - |> Async.RunSynchronously - let results = Assert.NotNull (test()) - Check.Quick results - - [] - let ``RequestTextFromFile does not return a null when using desktop-clock-info`` () = - let test ()= - Pancake.RequestTextFromFileAsync (ValidGibberishLevelInput()) (ValidSentencesInput()) DesktopClock - |> Async.RunSynchronously - let results = Assert.NotNull (test()) - Check.Quick results - - [] - let ``RequestTextFromFile does not return a null when using word-generator`` () = - let test () = - Pancake.RequestTextFromFileAsync (ValidGibberishLevelInput()) (ValidSentencesInput()) WordGenerator - |> Async.RunSynchronously - let results = Assert.NotNull (test()) - Check.Quick results - - [] - let ``RequestTextFromFile does not return a null when using test-post`` () = - let test () = - Pancake.RequestTextFromFileAsync (ValidGibberishLevelInput()) (ValidSentencesInput()) TestPost - |> Async.RunSynchronously - let results = Assert.NotNull (test()) - Check.Quick results - - [] - let ``RequestAllTemplateFiles does not return a null`` () = - let test () = - Pancake.RequestAllTemplateFilesAsync () - |> Async.RunSynchronously - let results = Assert.NotNull (test()) - Check.Quick results - *) - module ``Contents Test`` = [] @@ -266,4 +185,16 @@ |> Async.RunSynchronously |> EndsAsIntended let results () = Assert.True(test()) + Check.Quick (results()) + + [] + let ``TextInFileIsValid returns true when processing the text in the template files`` () = + (* The template .txt files validity have been tested above. + This test is to for the function, not the .txt files. + Something has gone wrong if there are not quite a lot of explicit template file tests above. + This is why the .txt files are called at random and not broken down into seperate tests. *) + let test () = + Pancake.TextInFileIsValidAsync (ValidFileInput()) + |> Async.RunSynchronously + let results () = Assert.True (test()) Check.Quick (results()) \ No newline at end of file diff --git a/TestCentre/TestCentre.fsproj b/TestCentre/TestCentre.fsproj index 523af0d..8b00856 100644 --- a/TestCentre/TestCentre.fsproj +++ b/TestCentre/TestCentre.fsproj @@ -75,6 +75,7 @@ PreserveNewest + diff --git a/TestCentre/TestingConstants.fs b/TestCentre/TestingConstants.fs index decc141..1d5be43 100644 --- a/TestCentre/TestingConstants.fs +++ b/TestCentre/TestingConstants.fs @@ -1,21 +1,33 @@ module internal TestingConstants -// Use these to reference the built-in .txt files in Test Centre. +(* Valid Text Files +=================================================================================================================== +Use these to quickly reference the built-in .txt files within Test Centre. +They should, also, mimic the .txt files in Wet Pancake/textFiles. +If you are noticing inconsistent behaviour between Test Centre and Wet Pancake, make sure these files match. *) + +[] +let ConsoleWaterworks = __SOURCE_DIRECTORY__ + @"\TextFiles\console-waterworks-announcement.txt" [] let DesktopClock = __SOURCE_DIRECTORY__ + @"\TextFiles\desktop-clock-info.txt" [] -let ConsoleWaterworks = __SOURCE_DIRECTORY__ + @"\TextFiles\console-waterworks-announcement.txt" +let TestPost = __SOURCE_DIRECTORY__ + @"\TextFiles\test-post.txt" [] let WordGenerator = __SOURCE_DIRECTORY__ + @"\TextFiles\word-generator.txt" -[] -let TestPost = __SOURCE_DIRECTORY__ + @"\TextFiles\test-post.txt" +(* Invalid Input +=================================================================================================================== +These values should not mimic or reference anything in Wet Pancake. +Below should just be dummy content/values. *) [] let InvalidFilePathInput = __SOURCE_DIRECTORY__ + @"Invalid/file.txt" [] let InvalidFileTypeInput = __SOURCE_DIRECTORY__ + @"\TextFiles\desktop-clock-info.doc" + +[] +let InvalidTextFile = __SOURCE_DIRECTORY__ + @"\TextFiles\invalid-text.txt" diff --git a/TestCentre/TextFiles/invalid-text.txt b/TestCentre/TextFiles/invalid-text.txt new file mode 100644 index 0000000..234482a --- /dev/null +++ b/TestCentre/TextFiles/invalid-text.txt @@ -0,0 +1 @@ +This file does not contain a vaild end token diff --git a/TestCentre/UnitTests.fs b/TestCentre/UnitTests.fs index e2f1b1d..6892ef5 100644 --- a/TestCentre/UnitTests.fs +++ b/TestCentre/UnitTests.fs @@ -14,25 +14,30 @@ The WetPancake library does not expose the file access functions so the .txt files are mirrored here (in Test Centre). The mirroring, also, doubles up as sample files to pass into WetPancake. *) - [] - let ``desktop-clock-info can be found`` () = - let result = File.Exists DesktopClock - Assert.Equal(true, result); - [] let ``console-waterworks-announcements can be found`` () = let result = File.Exists ConsoleWaterworks - Assert.Equal(true, result); - + Assert.True result + [] - let ``word-generator can be found`` () = - let result = File.Exists WordGenerator - Assert.Equal(true, result); + let ``desktop-clock-info can be found`` () = + let result = File.Exists DesktopClock + Assert.True result + [] + let ``invalid-text can be found`` () = + let result = File.Exists InvalidTextFile + Assert.True result + [] let ``test-post can be found`` () = let result = File.Exists TestPost - Assert.Equal(true, result) + Assert.True result + + [] + let ``word-generator can be found`` () = + let result = File.Exists WordGenerator + Assert.True result module ``Null Tests`` = @@ -110,6 +115,11 @@ Pancake.RequestTextFromFileAsync (ValidGibberishLevelInput()) (ValidSentencesInput()) TestPost Assert.NotNull result + [] + let ``TextIsValid does not return a null`` () = + let result = Pancake.TextInFileIsValidAsync TestPost + Assert.NotNull result + module ``Contents Tests`` = [] @@ -267,4 +277,19 @@ Pancake.RequestTextFromFileAsync (ValidGibberishLevelInput()) (ValidSentencesInput()) WordGenerator |> Async.RunSynchronously |> EndsAsIntended - Assert.True(result) \ No newline at end of file + Assert.True(result) + + [] + let ``TextInFileIsValid returns correct boolean value when processing a files text`` () = + let trueResult = + Pancake.TextInFileIsValidAsync TestPost + |> Async.RunSynchronously + let falseResult = + Pancake.TextInFileIsValidAsync InvalidTextFile + |> Async.RunSynchronously + let outcomes = (trueResult, falseResult) + let finalResult = + match outcomes with + | true, false -> true + | _, _ -> false + Assert.True finalResult \ No newline at end of file diff --git a/WetPancake/DataProcessing.fs b/WetPancake/DataProcessing.fs index 5d2ec76..12b524b 100644 --- a/WetPancake/DataProcessing.fs +++ b/WetPancake/DataProcessing.fs @@ -29,6 +29,13 @@ raise (FileNotFoundException("Unable to find the file at the location specified.")) | _ -> ignore + let TextContainsValidEndToken (text: string) = + match text with + | text when text.Contains "." -> true + | text when text.Contains "!" -> true + | text when text.Contains "?" -> true + | _ -> false + let SortIntoGroups groupSize text = SplitText @"\s+" text // Splits text where there is a space. |> Seq.windowed groupSize diff --git a/WetPancake/DataServices.fs b/WetPancake/DataServices.fs index a18695f..d29eeeb 100644 --- a/WetPancake/DataServices.fs +++ b/WetPancake/DataServices.fs @@ -93,5 +93,4 @@ |> Array.take noOfSentences |> ConcatToString |> ReplaceArtifact " " - |> TrimEnd [|' '|] - \ No newline at end of file + |> TrimEnd [|' '|] \ No newline at end of file diff --git a/WetPancake/ProductServices.fs b/WetPancake/ProductServices.fs index a0d464c..88d0489 100644 --- a/WetPancake/ProductServices.fs +++ b/WetPancake/ProductServices.fs @@ -18,14 +18,21 @@ module Pancake = /// /// /// The number of sentences the cleaned string should have. + /// This should be smaller than the number of sentences the original text has. /// /// /// The string to clean. /// + /// + /// A string of text which has been trimmed to the specified sentence count. + /// + /// + /// Thrown when the number of sentences requested is bigger than the number in the text passed in. + /// /// /// This function's aim is to trim or remove excess sentences. /// If the string has less sentences than the number requested, it will not change. - /// + /// let CleanResultAsync noOfSentences text = async { try @@ -37,6 +44,22 @@ module Pancake = | :? InvalidOperationException -> return text } + /// + /// Checks the text within the specified file to see if it contains a vaild end token. + /// They are '.', '!' and '?'. + /// + /// + /// The path of the .txt file being tested. + /// + /// + /// This function does not check to see if the filepath is valid. + /// Be sure to check the path is valid before calling this function. + /// + let TextInFileIsValidAsync filePath = + async { + return DataAccess.LoadFile filePath |> TextContainsValidEndToken + } + /// /// An asynchronous function which generates random text. /// @@ -46,7 +69,7 @@ module Pancake = /// /// This function will produce a maximum of 10 sentences with each function call. /// - let RequestRandomTextAsync() = + let RequestRandomTextAsync () = async { let data = LoadFile (SelectRandomSampleFile()) @@ -140,7 +163,10 @@ module Pancake = try GibberishLevelIsValid gibberishLevel |> ignore SentencesIsValid sentences |> ignore - FilePathIsValid |> ignore + FilePathIsValid filePath |> ignore + let! textIsValid = TextInFileIsValidAsync filePath + if textIsValid = true then ignore () + else failwith @"The .txt file does not contain an end token ('.', '!' or '?')." let data = LoadFile filePath |> ApplyStandardSetup @@ -150,6 +176,7 @@ module Pancake = with | :? ArgumentException as ex -> return ex.Message | :? FileNotFoundException as ex -> return ex.Message + | :? SystemException as ex -> return ex.Message } /// diff --git a/WetPancake/Script.fsx b/WetPancake/Script.fsx index 4e0c751..2a03545 100644 --- a/WetPancake/Script.fsx +++ b/WetPancake/Script.fsx @@ -115,6 +115,12 @@ let dp_filePathIsValidException = | :? ArgumentException as ex -> ex.Message | :? FileNotFoundException as ex -> ex.Message +let dp_sentences = "This is a test setence." // Edit this to test (valid end token) +let dp_validEndToken () = + let result = TextContainsValidEndToken dp_sentences + result +printfn "Valid End Token: %b" (dp_validEndToken()) + // Data Structuring let ds_map = Map.empty let ds_text = [|"This"; "is"; "a"; "test"; "string."|] diff --git a/WetPancakeCLI/ConsoleCommands.cs b/WetPancakeCLI/ConsoleCommands.cs index a49f060..2d37c3a 100644 --- a/WetPancakeCLI/ConsoleCommands.cs +++ b/WetPancakeCLI/ConsoleCommands.cs @@ -20,6 +20,7 @@ namespace WetPancakeCLI static FSharpOption _taskCreationOptions = FSharpOption.None; static FSharpOption _cancellationToken = FSharpOption.None; + #region Console Utilities [ListCommand] [Description("Prints a test message to the console.")] [Parameters("None")] @@ -37,17 +38,24 @@ namespace WetPancakeCLI [Parameters("None")] [Usage("> Exit")] public static void Exit() => Environment.Exit(ExitCode); + #endregion + #region Wet Pancake Utilities [ListCommand] - [Description("Generates random text, the number of sentences generated is randomly determined.")] - [Parameters("None")] - [Usage("> GenerateRandomText")] - public static string GenerateRandomText() + [Description( + "Checks to see if the string matches the desired sentence count and removes any over that limit.\n" + + "If the string has less sentences than the number requested, it will not change.\n" + + "Sentences must be greater than 0 and text must contain at least 1 \".\" \"?\" \"!\"")] + [Parameters("sentences: int, text: string")] + [Usage("> CleanText 1 \"This is a test sentence. And, this one needs to be removed.\"")] + public static string CleanText(int sentences, string text) { try { + if (sentences < 1) + throw new ArgumentException("Invalid argument. Must be greater than 0", "sentences"); return FSharpAsync.StartAsTask - (RequestRandomTextAsync(), _taskCreationOptions, _cancellationToken).Result; + (CleanResultAsync(sentences, text), _taskCreationOptions, _cancellationToken).Result; } catch (Exception e) { @@ -57,26 +65,82 @@ namespace WetPancakeCLI } [ListCommand] - [Description("Generates text using the gibberish-level and number of sentences specified by the user.\n" + - "This command does not run the result through the extra \"cleaning\" process like GenerateCleanText.\n" + - "This means this command is faster but it might produce an extra sentence on the odd occasion.\n" + - "Use this if you prefer speed over accuracy.\n" + - "Gibberish-level must be between 2 and 20." - )] + [Description("Returns a list of all the available .txt files built-in to Wet Pancake.")] + [Parameters("None")] + [Usage("> RequestAllTemplateFiles")] + public static string RequestAllTemplateFiles() + { + try + { + WriteLine("Attempting to list out the available template files..."); + var files = + FSharpAsync.StartAsTask + (RequestAllTemplateFilesAsync(), _taskCreationOptions, _cancellationToken).Result; + foreach (var item in files) + { + WriteLine($"File path: {item}"); + } + return "Listing complete."; + } + catch (Exception e) + { + Debug.WriteLine(e.Message); + throw; + } + } + + [ListCommand] + [Description( + "Checks the text in the specified .txt file to see if it is compatible with this program.\n" + + "For a file to be compatible, it must be a .txt file and contain at least one '.', '!' or '?'.")] + [Parameters("filePath: string")] + [Usage("> ValidateFile \"C:/your-file.txt\"")] + public static string ValidateFile(string filePath) + { + try + { + WriteLine("Validating file. Please wait..."); + var extension = Path.GetExtension(filePath); + if (string.Equals(extension, ".txt")) + { + var isValid = + FSharpAsync.StartAsTask(TextInFileIsValidAsync(filePath), + _taskCreationOptions, _cancellationToken).Result; + return $"Is Valid: {isValid}"; + } + else + throw new FileLoadException("The file entered is not a plain text (.txt) file.", filePath); + } + catch (Exception e) + { + Debug.WriteLine(e.Message); + throw; + } + } + #endregion + + #region Text Generation + [ListCommand] + [Description( + "Generates text using the gibberish-level and number of sentences specified by the user.\n" + + "The result goes through an extra \"cleaning\" process to remove any artefact sentences.\n" + + "Use this if you cannot tolerate the odd extra sentence.\n" + + "With that said, it does mean it is slower than its GenerateText counterpart.\n" + + "Gibberish-level must be between 2 and 20.")] [Parameters("gibberish-level: int, sentences: int")] - [Usage("> GenerateText 5 10")] - public static string GenerateText(int gibberishLevel, int sentences) + [Usage("> GenerateCleanText 5 10")] + public static string GenerateCleanText(int gibberishLevel, int sentences) { try { if (gibberishLevel < 2 || gibberishLevel > 20) throw new ArgumentException - ("Invalid argument. Must be between 2 and 20 (inclusive).", "gibberish-level"); + ("Invalid argument. Must be between 2 and 20 (inclusive).", "gibberish-Level"); if (sentences < 1) throw new ArgumentException ("Invalid argument. Must be greater than 0.", "sentences"); return FSharpAsync.StartAsTask - (RequestTextAsync(gibberishLevel, sentences), _taskCreationOptions, _cancellationToken).Result; + (RequestCleanTextAsync(gibberishLevel, sentences), _taskCreationOptions, _cancellationToken).Result; } catch (Exception e) { @@ -86,28 +150,31 @@ namespace WetPancakeCLI } [ListCommand] - [Description("Loads the specified .txt file and generates text based on it using the gibberish-level and number of sentences specified by the user.\n" + - "This command does not run the result through the extra \"cleaning\" process like GenerateCleanTextFromFile.\n" + - "This means this command is faster but it might produce an extra sentence on the odd occasion.\n" + - "Use this if you prefer speed over accuracy.\n" + - "Gibberish-level must be between 2 and 20.")] + [Description( + "Loads the specified .txt file and generates text based on it," + + "using the gibberish-level and number of sentences specified by the user.\n" + + "The result goes through an extra \"cleaning\" process to remove any artefact sentences.\n" + + "Use this if you cannot tolerate the odd extra sentence.\n" + + "With that said, it does mean it is slower than its GenerateTextFromFile counterpart.\n" + + "Gibberish-level must be between 2 and 20.")] [Parameters("gibberish-level: int, sentences: int, file path: string")] - [Usage("> GenerateTextFromFile 3 6 C:/yourfile.txt")] - public static string GenerateTextFromFile(int gibberishLevel, int sentences, string filePath) + [Usage("> GenerateCleanTextFromFile 3 6 C:/yourfile.txt")] + public static string GenerateCleanTextFromFile(int gibberishLevel, int sentences, string filePath) { try { if (gibberishLevel < 2 || gibberishLevel > 20) throw new ArgumentException - ("Invalid argument. Must be between 2 and 20 (inclusive).", "gibberish-level"); + ("Invalid argument. Must be between 2 and 20 (inclusive).", "gibberish-Level"); if (sentences < 1) throw new ArgumentException ("Invalid argument. Must be greater than 0.", "sentences"); - if (Path.GetExtension(filePath) != ".txt") + var extension = Path.GetExtension(filePath); + if (string.Equals(extension, ".txt") != true) throw new FileLoadException ("The file entered is not a plain text (.txt) file.", filePath); return FSharpAsync.StartAsTask - (RequestTextFromFileAsync(gibberishLevel, sentences, filePath), _taskCreationOptions, _cancellationToken).Result; + (RequestCleanTextFromFileAsync(gibberishLevel, sentences, filePath), _taskCreationOptions, _cancellationToken).Result; } catch (Exception e) { @@ -117,20 +184,15 @@ namespace WetPancakeCLI } [ListCommand] - [Description("Returns a list of all the available .txt files built-in to Wet Pancake.")] + [Description("Generates random text, the number of sentences generated is randomly determined.")] [Parameters("None")] - [Usage("> RequestAllTemplateFiles")] - public static string RequestAllTemplateFiles() + [Usage("> GenerateRandomText")] + public static string GenerateRandomText() { try { - WriteLine("Attempting to list out the available template files..."); - var files = FSharpAsync.StartAsTask(RequestAllTemplateFilesAsync(), _taskCreationOptions, _cancellationToken).Result; - foreach (var item in files) - { - WriteLine($"File path: {item}"); - } - return "Listing complete."; + return FSharpAsync.StartAsTask + (RequestRandomTextAsync(), _taskCreationOptions, _cancellationToken).Result; } catch (Exception e) { @@ -140,25 +202,26 @@ namespace WetPancakeCLI } [ListCommand] - [Description("Generates text using the gibberish-level and number of sentences specified by the user.\n" + - "The result goes through an extra \"cleaning\" process to remove any artefact sentences.\n" + - "Use this if you cannot tolerate the odd extra sentence.\n" + - "With that said, it does mean it is slower than its GenerateText counterpart.\n" + - "Gibberish-level must be between 2 and 20.")] + [Description( + "Generates text using the gibberish-level and number of sentences specified by the user.\n" + + "This command does not run the result through the extra \"cleaning\" process like GenerateCleanText.\n" + + "This means this command is faster but it might produce an extra sentence on the odd occasion.\n" + + "Use this if you prefer speed over accuracy.\n" + + "Gibberish-level must be between 2 and 20.")] [Parameters("gibberish-level: int, sentences: int")] - [Usage("> GenerateCleanText 5 10")] - public static string GenerateCleanText(int gibberishLevel, int sentences) + [Usage("> GenerateText 5 10")] + public static string GenerateText(int gibberishLevel, int sentences) { try { if (gibberishLevel < 2 || gibberishLevel > 20) throw new ArgumentException - ("Invalid argument. Must be between 2 and 20 (inclusive).", "gibberish-Level"); + ("Invalid argument. Must be between 2 and 20 (inclusive).", "gibberish-level"); if (sentences < 1) throw new ArgumentException ("Invalid argument. Must be greater than 0.", "sentences"); return FSharpAsync.StartAsTask - (RequestCleanTextAsync(gibberishLevel, sentences), _taskCreationOptions, _cancellationToken).Result; + (RequestTextAsync(gibberishLevel, sentences), _taskCreationOptions, _cancellationToken).Result; } catch (Exception e) { @@ -168,50 +231,35 @@ namespace WetPancakeCLI } [ListCommand] - [Description("Loads the specified .txt file and generates text based on it, using the gibberish-level and number of specified by the user.\n" + - "The result goes through an extra \"cleaning\" process to remove any artefact sentences.\n" + - "Use this if you cannot tolerate the odd extra sentence.\n" + - "With that said, it does mean it is slower than its GenerateTextFromFile counterpart.\n" + - "Gibberish-level must be between 2 and 20.")] + [Description( + "Loads the specified .txt file and generates text based on it using the gibberish-level and number of sentencesspecifiedby the user.\n" + + "This command does not run the result through the extra \"cleaning\" process like GenerateCleanTextFromFile.\n" + + "This means this command is faster but it might produce an extra sentence on the odd occasion.\n" + + "Use this if you prefer speed over accuracy.\n" + + "Gibberish-level must be between 2 and 20.")] [Parameters("gibberish-level: int, sentences: int, file path: string")] - [Usage("> GenerateCleanTextFromFile 3 6 C:/yourfile.txt")] - public static string GenerateCleanTextFromFile(int gibberishLevel, int sentences, string filePath) + [Usage("> GenerateTextFromFile 3 6 C:/yourfile.txt")] + public static string GenerateTextFromFile(int gibberishLevel, int sentences, string filePath) { try { if (gibberishLevel < 2 || gibberishLevel > 20) throw new ArgumentException - ("Invalid argument. Must be between 2 and 20 (inclusive).", "gibberish-Level"); + ("Invalid argument. Must be between 2 and 20 (inclusive).", "gibberish-level"); if (sentences < 1) throw new ArgumentException ("Invalid argument. Must be greater than 0.", "sentences"); - if (Path.GetExtension(filePath) != ".txt") + var extension = Path.GetExtension(filePath); + if (string.Equals(extension, ".txt") != true) throw new FileLoadException ("The file entered is not a plain text (.txt) file.", filePath); + var fileIsValid = + FSharpAsync.StartAsTask(TextInFileIsValidAsync(filePath), + _taskCreationOptions, _cancellationToken).Result; + if (fileIsValid == false) + throw new Exception("The .txt does not contain a vaild end token ('.', '!' or '?')."); return FSharpAsync.StartAsTask - (RequestCleanTextFromFileAsync(gibberishLevel, sentences, filePath), _taskCreationOptions, _cancellationToken).Result; - } - catch (Exception e) - { - Debug.WriteLine(e.Message); - throw; - } - } - - [ListCommand] - [Description("Checks to see if the string matches the desired sentence count and removes any over that limit.\n" + - "If the string has less sentences than the number requested, it will not change.\n" + - "Sentences must be greater than 0 and text must contain at least 1 \".\" \"?\" \"!\"")] - [Parameters("sentences: int, text: string")] - [Usage("> CleanText 1 \"This is a test sentence. And, this one needs to be removed.\"")] - public static string CleanText(int sentences, string text) - { - try - { - if (sentences < 1) - throw new ArgumentException ("Invalid argument. Must be greater than 0", "sentences"); - return FSharpAsync.StartAsTask - (CleanResultAsync(sentences, text), _taskCreationOptions, _cancellationToken).Result; + (RequestTextFromFileAsync(gibberishLevel, sentences, filePath), _taskCreationOptions, _cancellationToken).Result; } catch (Exception e) { @@ -219,5 +267,6 @@ namespace WetPancakeCLI throw; } } + #endregion } } diff --git a/WetPancakeCLI/Properties/AssemblyInfo.cs b/WetPancakeCLI/Properties/AssemblyInfo.cs index 6b44158..8b754ac 100644 --- a/WetPancakeCLI/Properties/AssemblyInfo.cs +++ b/WetPancakeCLI/Properties/AssemblyInfo.cs @@ -38,7 +38,7 @@ using System.Runtime.InteropServices; // 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("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] +[assembly: AssemblyVersion("0.8.0.0")] +[assembly: AssemblyFileVersion("0.8.0.0")] [assembly: NeutralResourcesLanguage("en-GB")]