From 786e3af1adf3d45f8ee94b130594c89e674710d5 Mon Sep 17 00:00:00 2001 From: Sebastien Rousseau Date: Sun, 21 Jan 2024 21:26:35 +0000 Subject: [PATCH 1/2] feat(wiserone): :sparkles: 0.0.3 add tests and support for CSV --- 2024_01_21index.html | 252 ------------------------------------------ Cargo.lock | 102 ++++++++++++++++- Cargo.toml | 4 +- README.md | 27 +++-- docs/sitemap.xml | 64 +++++------ examples/example.rs | 25 ++--- quotes/01-quotes.csv | 32 ++++++ src/ascii.rs | 2 +- src/cli.rs | 14 +-- src/html.rs | 3 +- src/lib.rs | 2 +- src/loggers.rs | 3 +- src/macros.rs | 4 + src/main.rs | 3 +- src/quotes.rs | 188 ++++++++++++++++--------------- src/sitemap.rs | 3 +- tests/test.rs | 2 - tests/test_ascii.rs | 26 +++++ tests/test_loggers.rs | 40 +++++++ tests/test_quotes.rs | 176 +++++++++++++++++++++++++++++ tests/test_sitemap.rs | 26 +++++ 21 files changed, 578 insertions(+), 420 deletions(-) delete mode 100644 2024_01_21index.html create mode 100644 quotes/01-quotes.csv delete mode 100644 tests/test.rs create mode 100644 tests/test_ascii.rs create mode 100644 tests/test_loggers.rs create mode 100644 tests/test_quotes.rs create mode 100644 tests/test_sitemap.rs diff --git a/2024_01_21index.html b/2024_01_21index.html deleted file mode 100644 index 3ec8705..0000000 --- a/2024_01_21index.html +++ /dev/null @@ -1,252 +0,0 @@ - - - - - - - - Dreams shape the future, but it's our relentless pursuit that builds it. - - - - - - - - - - - - - - - - - - - - - - - - -
- - Dreams shape the future, but it's our relentless pursuit that builds it. -

Dreams shape the future, but it's our relentless pursuit that builds it.

-

The Wiser One

- - - - - - - -
- - - - - - - - - - - - - - \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 2a1e327..63679c5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -286,6 +286,27 @@ version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" +[[package]] +name = "csv" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac574ff4d437a7b5ad237ef331c17ccca63c46479e5b5453eb8e10bb99a759fe" +dependencies = [ + "csv-core", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "csv-core" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5efa2b3d7902f4b634a20cae3c9c4e6209dc4779feb6863329607560143efa70" +dependencies = [ + "memchr", +] + [[package]] name = "deranged" version = "0.3.11" @@ -295,6 +316,12 @@ dependencies = [ "powerfmt", ] +[[package]] +name = "downcast" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1435fa1053d8b2fbbe9be7e97eca7f33d37b28409959813daefc1446a14247f1" + [[package]] name = "dtt" version = "0.0.5" @@ -372,6 +399,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" +[[package]] +name = "fragile" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c2141d6d6c8512188a7891b4b01590a45f6dac67afb4f255c4124dbb86d4eaa" + [[package]] name = "getrandom" version = "0.2.12" @@ -464,6 +497,12 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + [[package]] name = "libc" version = "0.2.152" @@ -518,6 +557,33 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "mockall" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43766c2b5203b10de348ffe19f7e54564b64f3d6018ff7648d1e2d6d3a0f0a48" +dependencies = [ + "cfg-if", + "downcast", + "fragile", + "lazy_static", + "mockall_derive", + "predicates", + "predicates-tree", +] + +[[package]] +name = "mockall_derive" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af7cbce79ec385a1d4f54baa90a76401eb15d9cab93685f62e7e9f942aa00ae2" +dependencies = [ + "cfg-if", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "num-traits" version = "0.2.17" @@ -681,6 +747,32 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +[[package]] +name = "predicates" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68b87bfd4605926cdfefc1c3b5f8fe560e3feca9d5552cf68c466d3d8236c7e8" +dependencies = [ + "anstyle", + "predicates-core", +] + +[[package]] +name = "predicates-core" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b794032607612e7abeb4db69adb4e33590fa6cf1149e95fd7cb00e634b92f174" + +[[package]] +name = "predicates-tree" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "368ba315fb8c5052ab692e68a0eefec6ec57b23a36959c14496f0b0df2c0cecf" +dependencies = [ + "predicates-core", + "termtree", +] + [[package]] name = "proc-macro2" version = "1.0.78" @@ -933,6 +1025,12 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "termtree" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3369f5ac52d5eb6ab48c6b4ffdc8efbcad6b89c765749064ba298f2c68a16a76" + [[package]] name = "time" version = "0.3.31" @@ -1332,14 +1430,16 @@ dependencies = [ [[package]] name = "wiserone" -version = "0.0.2" +version = "0.0.3" dependencies = [ "anyhow", "clap", "criterion", + "csv", "dtt", "env_logger", "figlet-rs", + "mockall", "openssl", "rlg", "serde", diff --git a/Cargo.toml b/Cargo.toml index 9b43e9f..dd5934f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,7 +18,7 @@ name = "wiserone" readme = "README.md" repository = "https://github.com/sebastienrousseau/wiserone" rust-version = "1.75.0" -version = "0.0.2" +version = "0.0.3" include = [ "/benches/**", "/build.rs", @@ -43,6 +43,7 @@ debug = true [dependencies] anyhow = "1.0.79" clap = { version = "4.4.18", features = ["env", "derive"] } +csv = "1.3.0" dtt = "0.0.5" env_logger = "0.11.0" figlet-rs = "0.1.5" @@ -57,6 +58,7 @@ uuid = { version = "1.7.0", features = ["serde", "v4"] } [dev-dependencies] criterion = "0.5.1" +mockall = "0.12.1" [lib] crate-type = ["lib"] diff --git a/README.md b/README.md index 944e349..7689271 100644 --- a/README.md +++ b/README.md @@ -139,6 +139,8 @@ The [GitHub Actions][10] shows the platforms in which the `wiserone` library tes #### Generate a random quote +##### From JSON + The following command generates a random quote from the `quotes.json` file. ```shell @@ -151,12 +153,18 @@ or locally if you have cloned the repository: cargo run random ./quotes/01-quotes.json ``` +##### From CSV + +The following command generates a random quote from the `quotes.csv` file. + +```shell +wiserone --random ./quotes/01-quotes.csv +``` -Have a look at the `tests/data/mylibrary.csv` file for an example and -feel free to use it for your own library as a template. +or locally if you have cloned the repository: ```shell -libmake --csv tests/data/mylibrary.csv +cargo run random ./quotes/01-quotes.csv ``` To use the `wiserone` library in your project, add the following to your @@ -164,13 +172,12 @@ To use the `wiserone` library in your project, add the following to your ```toml [dependencies] -wiserone = "0.0.2" +wiserone = "0.0.3" ``` Add the following to your `main.rs` file: ```rust -extern crate wiserone; use wiserone::*; ``` @@ -220,14 +227,14 @@ providing a lot of useful suggestions on how to improve this project. [0]: https://wiserone.com [2]: http://opensource.org/licenses/MIT -[3]: https://github.com/sebastienrousseau/wiserone/wiserone/issues -[4]: https://github.com/sebastienrousseau/wiserone/wiserone/blob/main/CONTRIBUTING.md -[5]: https://github.com/sebastienrousseau/wiserone/wiserone/graphs/contributors +[3]: https://github.com/sebastienrousseau/wiserone/issues +[4]: https://github.com/sebastienrousseau/wiserone/blob/main/CONTRIBUTING.md +[5]: https://github.com/sebastienrousseau/wiserone/graphs/contributors [6]: http://semver.org/ [7]: https://crates.io/crates/wiserone [8]: https://docs.rs/wiserone [9]: https://lib.rs/crates/wiserone -[10]: https://github.com/sebastienrousseau/wiserone/wiserone/actions +[10]: https://github.com/sebastienrousseau/wiserone/actions [11]: https://www.rust-lang.org/policies/code-of-conduct [12]: https://www.reddit.com/r/rust/ [13]: https://www.rust-lang.org/learn/get-started @@ -235,6 +242,6 @@ providing a lot of useful suggestions on how to improve this project. [crates-badge]: https://img.shields.io/crates/v/wiserone.svg?style=for-the-badge 'Crates.io badge' [divider]: https://kura.pro/common/images/elements/divider.svg "divider" [docs-badge]: https://img.shields.io/docsrs/wiserone.svg?style=for-the-badge 'Docs.rs badge' -[libs-badge]: https://img.shields.io/badge/lib.rs-v0.0.2-orange.svg?style=for-the-badge 'Lib.rs badge' +[libs-badge]: https://img.shields.io/badge/lib.rs-v0.0.3-orange.svg?style=for-the-badge 'Lib.rs badge' [license-badge]: https://img.shields.io/crates/l/wiserone.svg?style=for-the-badge 'License badge' [made-with-rust-badge]: https://img.shields.io/badge/rust-f04041?style=for-the-badge&labelColor=c0282d&logo=rust 'Made With Rust badge' diff --git a/docs/sitemap.xml b/docs/sitemap.xml index 80f5b33..67eb158 100644 --- a/docs/sitemap.xml +++ b/docs/sitemap.xml @@ -3,161 +3,161 @@ https://wiserone.com/2024_01_18.html weekly - 2024-01-21 18:29:56.988526 +00:00:00 + 2024-01-21 21:25:51.211284 +00:00:00 https://wiserone.com/2024_01_22.html weekly - 2024-01-21 18:29:56.988526 +00:00:00 + 2024-01-21 21:25:51.211284 +00:00:00 https://wiserone.com/2024_01_02.html weekly - 2024-01-21 18:29:56.988526 +00:00:00 + 2024-01-21 21:25:51.211284 +00:00:00 https://wiserone.com/2024_01_14.html weekly - 2024-01-21 18:29:56.988526 +00:00:00 + 2024-01-21 21:25:51.211284 +00:00:00 https://wiserone.com/index.html weekly - 2024-01-21 18:29:56.988526 +00:00:00 + 2024-01-21 21:25:51.211284 +00:00:00 https://wiserone.com/2024_01_15.html weekly - 2024-01-21 18:29:56.988526 +00:00:00 + 2024-01-21 21:25:51.211284 +00:00:00 https://wiserone.com/2024_01_03.html weekly - 2024-01-21 18:29:56.988526 +00:00:00 + 2024-01-21 21:25:51.211284 +00:00:00 https://wiserone.com/2024_01_23.html weekly - 2024-01-21 18:29:56.988526 +00:00:00 + 2024-01-21 21:25:51.211284 +00:00:00 https://wiserone.com/2024_01_19.html weekly - 2024-01-21 18:29:56.988526 +00:00:00 + 2024-01-21 21:25:51.211284 +00:00:00 https://wiserone.com/2024_01_04.html weekly - 2024-01-21 18:29:56.988526 +00:00:00 + 2024-01-21 21:25:51.211284 +00:00:00 https://wiserone.com/2024_01_12.html weekly - 2024-01-21 18:29:56.988526 +00:00:00 + 2024-01-21 21:25:51.211284 +00:00:00 https://wiserone.com/2024_01_28.html weekly - 2024-01-21 18:29:56.988526 +00:00:00 + 2024-01-21 21:25:51.211284 +00:00:00 https://wiserone.com/2024_01_08.html weekly - 2024-01-21 18:29:56.988526 +00:00:00 + 2024-01-21 21:25:51.211284 +00:00:00 https://wiserone.com/2024_01_24.html weekly - 2024-01-21 18:29:56.988526 +00:00:00 + 2024-01-21 21:25:51.211284 +00:00:00 https://wiserone.com/2024_01_25.html weekly - 2024-01-21 18:29:56.988526 +00:00:00 + 2024-01-21 21:25:51.211284 +00:00:00 https://wiserone.com/2024_01_09.html weekly - 2024-01-21 18:29:56.988526 +00:00:00 + 2024-01-21 21:25:51.211284 +00:00:00 https://wiserone.com/2024_01_29.html weekly - 2024-01-21 18:29:56.988526 +00:00:00 + 2024-01-21 21:25:51.211284 +00:00:00 https://wiserone.com/2024_01_13.html weekly - 2024-01-21 18:29:56.988526 +00:00:00 + 2024-01-21 21:25:51.211284 +00:00:00 https://wiserone.com/2024_01_05.html weekly - 2024-01-21 18:29:56.988526 +00:00:00 + 2024-01-21 21:25:51.211284 +00:00:00 https://wiserone.com/2024_01_10.html weekly - 2024-01-21 18:29:56.988526 +00:00:00 + 2024-01-21 21:25:51.211284 +00:00:00 https://wiserone.com/2024_01_06.html weekly - 2024-01-21 18:29:56.988526 +00:00:00 + 2024-01-21 21:25:51.211284 +00:00:00 https://wiserone.com/2024_01_26.html weekly - 2024-01-21 18:29:56.988526 +00:00:00 + 2024-01-21 21:25:51.211284 +00:00:00 https://wiserone.com/2024_01_30.html weekly - 2024-01-21 18:29:56.988526 +00:00:00 + 2024-01-21 21:25:51.211284 +00:00:00 https://wiserone.com/2024_01_31.html weekly - 2024-01-21 18:29:56.988526 +00:00:00 + 2024-01-21 21:25:51.211284 +00:00:00 https://wiserone.com/2024_01_27.html weekly - 2024-01-21 18:29:56.988526 +00:00:00 + 2024-01-21 21:25:51.211284 +00:00:00 https://wiserone.com/2024_01_07.html weekly - 2024-01-21 18:29:56.988526 +00:00:00 + 2024-01-21 21:25:51.211284 +00:00:00 https://wiserone.com/2024_01_11.html weekly - 2024-01-21 18:29:56.988526 +00:00:00 + 2024-01-21 21:25:51.211284 +00:00:00 https://wiserone.com/2024_01_20.html weekly - 2024-01-21 18:29:56.988526 +00:00:00 + 2024-01-21 21:25:51.211284 +00:00:00 https://wiserone.com/2024_01_16.html weekly - 2024-01-21 18:29:56.988526 +00:00:00 + 2024-01-21 21:25:51.211284 +00:00:00 https://wiserone.com/2024_01_01.html weekly - 2024-01-21 18:29:56.988526 +00:00:00 + 2024-01-21 21:25:51.211284 +00:00:00 https://wiserone.com/2024_01_17.html weekly - 2024-01-21 18:29:56.988526 +00:00:00 + 2024-01-21 21:25:51.211284 +00:00:00 https://wiserone.com/2024_01_21.html weekly - 2024-01-21 18:29:56.988526 +00:00:00 + 2024-01-21 21:25:51.211284 +00:00:00 \ No newline at end of file diff --git a/examples/example.rs b/examples/example.rs index 1db3f96..15b299c 100644 --- a/examples/example.rs +++ b/examples/example.rs @@ -1,44 +1,39 @@ // Copyright notice and licensing information. -// Copyright © 2024 WiserOne. All rights reserved. +// Copyright © 2024 The Wiser One. All rights reserved. // SPDX-License-Identifier: MIT OR Apache-2.0 extern crate wiserone; // Importing necessary modules and traits from the standard library and `wiserone` crate. +use serde_json::to_string_pretty; use std::error::Error; use wiserone::html::generate_html_file; -use wiserone::quotes::read_and_parse_quotes; -use wiserone::run; +use wiserone::quotes::read_quotes_from_file; // The `main` function is the entry point of the program. // It returns a Result type, indicating that it might return an error. fn main() -> Result<(), Box> { - // Calling the `run` function from the `wiserone` crate. - // This function encapsulates the main application logic. - println!("Running the main application logic:"); - run()?; - // Reading and parsing quotes from a JSON file. // The function `read_and_parse_quotes` is expected to read a JSON file, // parse it, and return a collection of quotes. println!("Reading and parsing quotes from a JSON file:"); - let mut quotes = read_and_parse_quotes("./quotes/01-quotes.json")?; - println!("Quotes: {:?}", quotes); + let mut quotes = read_quotes_from_file("./quotes/01-quotes.json")?; + let json_string = to_string_pretty("es).unwrap(); + println!("Quotes:\n{}\n", json_string); // Selecting a random quote from the collection. - // This part assumes that the collection of quotes has a method - // `select_random_quote` which randomly selects and returns a quote. println!("Selecting a random quote:"); let random_quote = quotes.select_random_quote()?; - println!("Random Quote: {:?}", random_quote); + let json_string = to_string_pretty(&random_quote).unwrap(); + println!("Random Quote: {}\n", json_string); // Generating an HTML file that displays the random quote. // The function `generate_html_file` takes a filename and a quote, // and creates an HTML file with the quote. println!("Generating an HTML file for the random quote:"); - let filename = "example_quote.html"; + let filename = "../examples/example_quote.html"; generate_html_file(filename, random_quote)?; - println!("Generated HTML file: {}", filename); + println!("Generated HTML file: {}\n", filename); // If everything executes successfully, return Ok. Ok(()) diff --git a/quotes/01-quotes.csv b/quotes/01-quotes.csv new file mode 100644 index 0000000..1490472 --- /dev/null +++ b/quotes/01-quotes.csv @@ -0,0 +1,32 @@ +quote_text,author,date_added,image_url +"Innovation is not about saying yes to everything, but about saying no to all but the most crucial features.",The Wiser One,2024-01-01T06:06:06Z,https://kura.pro/stock/images/banners/vitalis-hirschmann-4ErRQkRiOv4.webp +"Simplicity is the ultimate sophistication, where complexity is peeled away to reveal the essence.",The Wiser One,2024-01-02T06:06:06Z,https://kura.pro/stock/images/banners/vitalis-hirschmann-4ErRQkRiOv4.webp +"True genius lies not in doing the extraordinary, but in elevating the ordinary.",The Wiser One,2024-01-03T06:06:06Z,https://kura.pro/stock/images/banners/vitalis-hirschmann-4ErRQkRiOv4.webp +The people who are crazy enough to think they can change the world are the ones who do.,The Wiser One,2024-01-04T06:06:06Z,https://kura.pro/stock/images/banners/vitalis-hirschmann-4ErRQkRiOv4.webp +Focus is about saying no to a thousand good ideas to embrace the one great idea that truly matters.,The Wiser One,2024-01-05T06:06:06Z,https://kura.pro/stock/images/banners/vitalis-hirschmann-4ErRQkRiOv4.webp +"To innovate, you must be willing to embrace the discomfort of uncertainty.",The Wiser One,2024-01-06T06:06:06Z,https://kura.pro/stock/images/banners/vitalis-hirschmann-4ErRQkRiOv4.webp +Greatness is achieved when passion and persistence challenge the impossible.,The Wiser One,2024-01-07T06:06:06Z,https://kura.pro/stock/images/banners/vitalis-hirschmann-4ErRQkRiOv4.webp +The future is shaped by those who dare to believe that their vision can become a reality.,The Wiser One,2024-01-08T06:06:06Z,https://kura.pro/stock/images/banners/vitalis-hirschmann-4ErRQkRiOv4.webp +Creativity is connecting things where others see no connection.,The Wiser One,2024-01-09T06:06:06Z,https://kura.pro/stock/images/banners/vitalis-hirschmann-4ErRQkRiOv4.webp +The greatest innovations are those that improve lives in ways people never imagined.,The Wiser One,2024-01-10T06:06:06Z,https://kura.pro/stock/images/banners/vitalis-hirschmann-4ErRQkRiOv4.webp +"Enduring success comes not from the frequency of innovation, but from the depth of understanding.",The Wiser One,2024-01-11T06:06:06Z,https://kura.pro/stock/images/banners/vitalis-hirschmann-4ErRQkRiOv4.webp +The most powerful tool we have is the ability to think differently and challenge the status quo.,The Wiser One,2024-01-12T06:06:06Z,https://kura.pro/stock/images/banners/vitalis-hirschmann-4ErRQkRiOv4.webp +Every significant achievement starts with the courage to pursue what seems impossible.,The Wiser One,2024-01-13T06:06:06Z,https://kura.pro/stock/images/banners/vitalis-hirschmann-4ErRQkRiOv4.webp +"In the orchestra of innovation, technology is an instrument, not the composer.",The Wiser One,2024-01-14T06:06:06Z,https://kura.pro/stock/images/banners/vitalis-hirschmann-4ErRQkRiOv4.webp +Vision without execution is just a daydream; execution without vision is just a chore.,The Wiser One,2024-01-15T06:06:06Z,https://kura.pro/stock/images/banners/vitalis-hirschmann-4ErRQkRiOv4.webp +Life's most profound lessons are often found in the simplest moments.,The Wiser One,2024-01-16T06:06:06Z,https://kura.pro/stock/images/banners/vitalis-hirschmann-4ErRQkRiOv4.webp +"In the pursuit of knowledge, every day is a new chapter full of possibilities.",The Wiser One,2024-01-17T06:06:06Z,https://kura.pro/stock/images/banners/vitalis-hirschmann-4ErRQkRiOv4.webp +"Great leaders don't just provide answers, they inspire questions.",The Wiser One,2024-01-18T06:06:06Z,https://kura.pro/stock/images/banners/vitalis-hirschmann-4ErRQkRiOv4.webp +"Breakthroughs come from breaking with tradition, not from following it.",The Wiser One,2024-01-19T06:06:06Z,https://kura.pro/stock/images/banners/vitalis-hirschmann-4ErRQkRiOv4.webp +The essence of creativity lies in a mind that questions what others accept.,The Wiser One,2024-01-20T06:06:06Z,https://kura.pro/stock/images/banners/vitalis-hirschmann-4ErRQkRiOv4.webp +"Dreams shape the future, but it's our relentless pursuit that builds it.",The Wiser One,2024-01-21T06:06:06Z,https://kura.pro/stock/images/banners/vitalis-hirschmann-4ErRQkRiOv4.webp +"In the realm of ideas, fear is the only enemy that needs to be defeated.",The Wiser One,2024-01-22T06:06:06Z,https://kura.pro/stock/images/banners/vitalis-hirschmann-4ErRQkRiOv4.webp +"Innovation isn't just about creating new paths; sometimes, it's about illuminating the ones we've overlooked.",The Wiser One,2024-01-23T06:06:06Z,https://kura.pro/stock/images/banners/vitalis-hirschmann-4ErRQkRiOv4.webp +"Change is not just a goal or a process, but a mindset that questions the familiar.",The Wiser One,2024-01-24T06:06:06Z,https://kura.pro/stock/images/banners/vitalis-hirschmann-4ErRQkRiOv4.webp +"Progress requires not just action, but the willingness to face the unknown.",The Wiser One,2024-01-25T06:06:06Z,https://kura.pro/stock/images/banners/vitalis-hirschmann-4ErRQkRiOv4.webp +"To lead is not to be the loudest in the room, but to be the beacon that guides others.",The Wiser One,2024-01-26T06:06:06Z,https://kura.pro/stock/images/banners/vitalis-hirschmann-4ErRQkRiOv4.webp +"Success is not measured by what we achieve alone, but by the journeys we inspire in others.",The Wiser One,2024-01-27T06:06:06Z,https://kura.pro/stock/images/banners/vitalis-hirschmann-4ErRQkRiOv4.webp +Curiosity is the compass that leads us to our passions.,The Wiser One,2024-01-28T06:06:06Z,https://kura.pro/stock/images/banners/vitalis-hirschmann-4ErRQkRiOv4.webp +"In a world that champions talking, listening is an undervalued superpower.",The Wiser One,2024-01-29T06:06:06Z,https://kura.pro/stock/images/banners/vitalis-hirschmann-4ErRQkRiOv4.webp +The most profound discoveries often lie just beyond the boundary of our comfort zone.,The Wiser One,2024-01-30T06:06:06Z,https://kura.pro/stock/images/banners/vitalis-hirschmann-4ErRQkRiOv4.webp +"In the canvas of life, every setback is a potential for a remarkable comeback.",The Wiser One,2024-01-31T06:06:06Z,https://kura.pro/stock/images/banners/vitalis-hirschmann-4ErRQkRiOv4.webp diff --git a/src/ascii.rs b/src/ascii.rs index 8b89f1a..ced4c9b 100644 --- a/src/ascii.rs +++ b/src/ascii.rs @@ -1,5 +1,5 @@ // Copyright notice and licensing information. -// Copyright © 2024 WiserOne. All rights reserved. +// Copyright © 2024 The Wiser One. All rights reserved. // SPDX-License-Identifier: MIT OR Apache-2.0 use figlet_rs::FIGfont; diff --git a/src/cli.rs b/src/cli.rs index 8ae6b31..4faa089 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -1,5 +1,5 @@ // Copyright notice and licensing information. -// Copyright © 2024 WiserOne. All rights reserved. +// Copyright © 2024 The Wiser One. All rights reserved. // SPDX-License-Identifier: MIT OR Apache-2.0 use clap::Parser; @@ -12,7 +12,7 @@ use rlg::{macro_log, LogFormat, LogLevel}; use crate::html::generate_html_file; use crate::sitemap::generate_sitemap_file; -use crate::quotes::{read_and_parse_quotes, read_and_parse_all_quotes}; +use crate::quotes::read_quotes_from_file; use crate::ascii::generate_ascii_art; #[derive(Parser)] @@ -23,13 +23,13 @@ use crate::ascii::generate_ascii_art; #[derive(Debug)] pub enum Command { - /// Selects a random quote from the JSON file and creates an HTML + /// Selects a random quote from the JSON or CSV file and creates an HTML /// file based on the quote. Random { - /// The name of the JSON file containing quotes. + /// The name of the JSON or CSV file containing quotes. filename: String, }, - /// Selects all quotes from the JSON file and creates an HTML file + /// Selects all quotes from the JSON or CSV file and creates an HTML file /// for each quote. All { /// The name of the JSON file containing quotes. @@ -88,7 +88,7 @@ pub fn run_cli() -> Result<(), Box> { let html_filename = format!("{}.html", date); // Read and parse quotes, then select a random quote - let mut quotes = read_and_parse_quotes(&filename)?; + let mut quotes = read_quotes_from_file(&filename)?; let quote = quotes.select_random_quote()?; generate_html_file(&html_filename, quote)?; generate_sitemap_file("https://wiserone.com/")?; @@ -96,7 +96,7 @@ pub fn run_cli() -> Result<(), Box> { Command::All { filename } => { println!("- info:wiserone: begin generating all quotes"); // Read and parse all quotes - let quotes = read_and_parse_all_quotes(&filename)?; + let quotes = read_quotes_from_file(&filename)?; // Generate an HTML file for each quote for quote in quotes.select_all_quotes()? { diff --git a/src/html.rs b/src/html.rs index b3e5942..c083244 100644 --- a/src/html.rs +++ b/src/html.rs @@ -1,6 +1,5 @@ // Copyright notice and licensing information. -// These lines indicate the copyright of the software and its licensing -// terms. Copyright © 2024 WiserOne. All rights reserved. +// Copyright © 2024 The Wiser One. All rights reserved. // SPDX-License-Identifier: MIT OR Apache-2.0 use dtt::DateTime; diff --git a/src/lib.rs b/src/lib.rs index 49a736d..fed9e39 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,5 @@ // Copyright notice and licensing information. -// Copyright © 2024 WiserOne. All rights reserved. +// Copyright © 2024 The Wiser One. All rights reserved. // SPDX-License-Identifier: MIT OR Apache-2.0 //! # `wiserone` 🦀 diff --git a/src/loggers.rs b/src/loggers.rs index 3ac8ee2..1e711f9 100644 --- a/src/loggers.rs +++ b/src/loggers.rs @@ -1,6 +1,5 @@ // Copyright notice and licensing information. -// These lines indicate the copyright of the software and its licensing -// terms. Copyright © 2024 WiserOne. All rights reserved. +// Copyright © 2024 The Wiser One. All rights reserved. // SPDX-License-Identifier: MIT OR Apache-2.0 //! Application logging functionality diff --git a/src/macros.rs b/src/macros.rs index 53f9b36..3401f6c 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -1,3 +1,7 @@ +// Copyright notice and licensing information. +// Copyright © 2024 The Wiser One. All rights reserved. +// SPDX-License-Identifier: MIT OR Apache-2.0 + //! # Macros for the `wiserone` crate. /// This macro takes any number of arguments and parses them into a diff --git a/src/main.rs b/src/main.rs index 965d5e1..432e198 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,5 @@ // Copyright notice and licensing information. -// These lines indicate the copyright of the software and its licensing -// terms. Copyright © 2024 WiserOne. All rights reserved. +// Copyright © 2024 The Wiser One. All rights reserved. // SPDX-License-Identifier: MIT OR Apache-2.0 //! The main function of the program. diff --git a/src/quotes.rs b/src/quotes.rs index 61b4787..dad1d69 100644 --- a/src/quotes.rs +++ b/src/quotes.rs @@ -1,89 +1,67 @@ -use std::error::Error; -use std::fs; +// Copyright notice and licensing information. +// Copyright © 2024 The Wiser One. All rights reserved. +// SPDX-License-Identifier: MIT OR Apache-2.0 +use csv; +use serde_json; use serde::{Deserialize, Serialize}; +use std::{error::Error, fmt, fs, path::Path}; use vrd::Random; -/// Struct representing a collection of quotes. -#[derive(Deserialize, Debug)] -pub struct Quotes { - /// Vector containing multiple `Quote` structs. - pub quotes: Vec, - /// Vector to track which quotes have been used. - pub used_indices: Vec, -} - /// Struct representing a single quote. -#[derive( - Clone, - Debug, - Deserialize, - Eq, - Hash, - Ord, - PartialEq, - PartialOrd, - Serialize, -)] +#[derive(Clone, Debug, Default, Deserialize, PartialEq, Serialize)] pub struct Quote { /// The text of the quote. pub quote_text: String, /// The author of the quote. pub author: String, - /// The date the quote was added. + /// The date when the quote was added to the JSON file. pub date_added: String, - /// URL of an image associated with the quote. + /// The URL of the image associated with the quote. pub image_url: String, } +/// Struct representing a collection of quotes. +#[derive(Clone, Debug, Default, Deserialize, PartialEq, Serialize)] +pub struct Quotes { + /// Vector of `Quote` structs. + pub quotes: Vec, +} + impl Quotes { - /// Initializes a new `Quotes` struct. + /// Initializes a new `Quotes` struct with the provided quotes. /// /// # Arguments /// - /// * `quotes` - Vector of `Quote` structs. - /// - /// # Returns - /// - /// Returns a `Quotes` instance with `used_indices` initialized to - /// track usage of quotes. + /// * `quotes` - A vector of `Quote` structs. pub fn new(quotes: Vec) -> Self { - let used_indices = vec![false; quotes.len()]; - Quotes { quotes, used_indices } + Quotes { quotes } } - /// Selects a random quote that has not been used yet. + /// Selects a random quote. /// /// # Returns /// /// Returns a reference to a randomly selected `Quote` or an error - /// if no available quotes. - pub fn select_random_quote( - &mut self, - ) -> Result<&Quote, Box> { - if self.quotes.is_empty() - || self.used_indices.iter().all(|&used| used) - { + /// if there are no quotes available. + pub fn select_random_quote(&mut self) -> Result<&Quote, Box> { + if self.quotes.is_empty() { return Err("No available quotes".into()); } + // Random number generator. let mut rng = Random::new(); - let mut rand_index = - rng.int(0, self.quotes.len() as i32 - 1) as usize; - - while self.used_indices[rand_index] { - rand_index = - rng.int(0, self.quotes.len() as i32 - 1) as usize; - } + // Random index selection. + let rand_index = rng.int(0, self.quotes.len() as i32 - 1) as usize; - self.used_indices[rand_index] = true; Ok(&self.quotes[rand_index]) } - /// Selects all quotes. + + /// Selects all quotes, sorted by the date added. /// /// # Returns /// - /// Returns all the quotes or an error if no available quotes. + /// Returns all quotes or an error if no quotes are available. pub fn select_all_quotes(&self) -> Result, Box> { if self.quotes.is_empty() { return Err("No available quotes".into()); @@ -95,57 +73,87 @@ impl Quotes { Ok(sorted_quotes) } } -/// Reads and parses quotes from a JSON file. -/// -/// # Arguments -/// -/// * `file_path` - Path to the JSON file containing quotes. -/// -/// # Returns -/// -/// Returns a `Quotes` struct if successful, or an error if the file -/// cannot be read or parsed. -pub fn read_and_parse_quotes( - file_path: &str, -) -> Result> { - let file_content = fs::read_to_string(file_path)?; - // Define a temporary struct to match the JSON structure - #[derive(Deserialize)] - struct TempQuotes { - quotes: Vec, +/// Custom error type for quote handling. +#[derive(Debug)] +pub enum QuoteError { + /// Error variant for I/O-related errors. + IOError(std::io::Error), + + /// General error variant for parsing errors. + ParseError(String), + + /// Error variant for when no quotes are available. + NoQuotesAvailable, +} + +impl fmt::Display for QuoteError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + QuoteError::IOError(err) => write!(f, "I/O Error: {}", err), + QuoteError::ParseError(msg) => write!(f, "Parse Error: {}", msg), + QuoteError::NoQuotesAvailable => write!(f, "No Quotes Available"), + } + } +} + +impl Error for QuoteError { + fn source(&self) -> Option<&(dyn Error + 'static)> { + match self { + QuoteError::IOError(err) => Some(err), + QuoteError::ParseError(_) => None, + QuoteError::NoQuotesAvailable => None, + } + } +} + +impl From for QuoteError { + fn from(error: std::io::Error) -> Self { + QuoteError::IOError(error) } +} - let temp_quotes: TempQuotes = serde_json::from_str(&file_content)?; +impl From for QuoteError { + fn from(error: serde_json::Error) -> Self { + QuoteError::ParseError(error.to_string()) + } +} - // Now use the `quotes` field from `TempQuotes` to initialize - // `Quotes` - Ok(Quotes::new(temp_quotes.quotes)) +impl From for QuoteError { + fn from(error: csv::Error) -> Self { + QuoteError::ParseError(error.to_string()) + } } -/// Reads and parses all the quotes from a JSON file. + +/// Reads and parses quotes from a file (either JSON or CSV). /// /// # Arguments /// -/// * `file_path` - Path to the JSON file containing quotes. +/// * `file_path` - Path to the file (JSON or CSV) containing quotes. /// /// # Returns /// -/// Returns all the `Quotes` struct if successful, or an error if the file +/// Returns a `Quotes` struct if successful, or an error if the file /// cannot be read or parsed. -pub fn read_and_parse_all_quotes( - file_path: &str, -) -> Result> { - let file_content = fs::read_to_string(file_path)?; - - // Define a temporary struct to match the JSON structure - #[derive(Deserialize)] - struct TempQuotes { - quotes: Vec, +pub fn read_quotes_from_file(file_path: &str) -> Result { + let path = Path::new(file_path); + match path.extension().and_then(|s| s.to_str()) { + Some("json") => read_quotes_from_json(file_path), + Some("csv") => read_quotes_from_csv(file_path), + _ => Err(QuoteError::ParseError("Unsupported file format".into())), } +} - let temp_quotes: TempQuotes = serde_json::from_str(&file_content)?; +/// Reads and parses quotes from a JSON file. +fn read_quotes_from_json(file_path: &str) -> Result { + let file_content = fs::read_to_string(file_path)?; + let quotes: Quotes = serde_json::from_str(&file_content)?; + Ok(quotes) +} - // Now use the `quotes` field from `TempQuotes` to initialize - // `Quotes` - Ok(Quotes::new(temp_quotes.quotes)) -} \ No newline at end of file +/// Reads and parses quotes from a CSV file. +fn read_quotes_from_csv(file_path: &str) -> Result { + let mut rdr = csv::Reader::from_path(file_path)?; + let quotes = rdr.deserialize().collect::, csv::Error>>()?; + Ok(Quotes::new(quotes)) +} diff --git a/src/sitemap.rs b/src/sitemap.rs index 34adb69..fbcca34 100644 --- a/src/sitemap.rs +++ b/src/sitemap.rs @@ -1,6 +1,5 @@ // Copyright notice and licensing information. -// These lines indicate the copyright of the software and its licensing -// terms. Copyright © 2024 WiserOne. All rights reserved. +// Copyright © 2024 The Wiser One. All rights reserved. // SPDX-License-Identifier: MIT OR Apache-2.0 use std::fs; diff --git a/tests/test.rs b/tests/test.rs deleted file mode 100644 index 5c6016f..0000000 --- a/tests/test.rs +++ /dev/null @@ -1,2 +0,0 @@ -#[cfg(test)] -mod tests {} diff --git a/tests/test_ascii.rs b/tests/test_ascii.rs new file mode 100644 index 0000000..643d9a6 --- /dev/null +++ b/tests/test_ascii.rs @@ -0,0 +1,26 @@ +// Copyright notice and licensing information. +// Copyright © 2024 The Wiser One. All rights reserved. +// SPDX-License-Identifier: MIT OR Apache-2.0 + +#[cfg(test)] +mod tests { + use wiserone::ascii::generate_ascii_art; + + #[test] + fn test_generate_ascii_art_successful() { + let text = "Hello, ASCII Art!"; + let result = generate_ascii_art(text); + assert!(result.is_ok()); + let ascii_art = result.unwrap(); + assert!(!ascii_art.is_empty()); + } + + #[test] + fn test_generate_ascii_art_failure() { + let text = "Hello, ASCII Art!"; + let result = generate_ascii_art(text); + assert!(result.is_ok()); + let ascii_art = result.unwrap(); + assert!(!ascii_art.is_empty()); + } +} diff --git a/tests/test_loggers.rs b/tests/test_loggers.rs new file mode 100644 index 0000000..e921d53 --- /dev/null +++ b/tests/test_loggers.rs @@ -0,0 +1,40 @@ +// Copyright notice and licensing information. +// Copyright © 2024 The Wiser One. All rights reserved. +// SPDX-License-Identifier: MIT OR Apache-2.0 + +#[cfg(test)] +mod tests { + + use rlg::macro_log; + use rlg::{LogFormat, LogLevel}; + + #[test] + fn test_logging() { + // Create a log entry + let log_entry = + macro_log!( + "session_id", + "time", + &LogLevel::INFO, + "component", + "Log message", + &LogFormat::CLF + ); + + // Define expected values + let expected_session_id = "session_id"; + let expected_time = "time"; + let expected_level = LogLevel::INFO; + let expected_component = "component"; + let expected_description = "Log message"; + let expected_format = LogFormat::CLF; + + // Assert that individual fields match the expected values + assert_eq!(log_entry.session_id, expected_session_id); + assert_eq!(log_entry.time, expected_time); + assert_eq!(log_entry.level, expected_level); + assert_eq!(log_entry.component, expected_component); + assert_eq!(log_entry.description, expected_description); + assert_eq!(log_entry.format, expected_format); + } +} \ No newline at end of file diff --git a/tests/test_quotes.rs b/tests/test_quotes.rs new file mode 100644 index 0000000..6b30b96 --- /dev/null +++ b/tests/test_quotes.rs @@ -0,0 +1,176 @@ +// Copyright notice and licensing information. +// Copyright © 2024 The Wiser One. All rights reserved. +// SPDX-License-Identifier: MIT OR Apache-2.0 + +use std::collections::HashSet; +use wiserone::quotes::{Quotes, Quote}; + +/// Test the creation and field access of the Quote struct. +#[test] +fn test_quote_struct() { + let quote = Quote { + quote_text: "Test quote".to_string(), + author: "Test author".to_string(), + date_added: "2024-01-21".to_string(), + image_url: "http://example.com/image.jpg".to_string(), + }; + + assert_eq!(quote.quote_text, "Test quote"); + assert_eq!(quote.author, "Test author"); + assert_eq!(quote.date_added, "2024-01-21"); + assert_eq!(quote.image_url, "http://example.com/image.jpg"); +} + +/// Test the initialization of the Quotes struct. +#[test] +fn test_quotes_struct_initialization() { + let quotes_vec = vec![ + Quote { + quote_text: "Quote 1".to_string(), + author: "Author 1".to_string(), + date_added: "2024-01-21".to_string(), + image_url: "http://example.com/image1.jpg".to_string(), + }, + Quote { + quote_text: "Quote 2".to_string(), + author: "Author 2".to_string(), + date_added: "2024-01-22".to_string(), + image_url: "http://example.com/image2.jpg".to_string(), + }, + ]; + + let quotes = Quotes::new(quotes_vec.clone()); + assert_eq!(quotes.quotes, quotes_vec); +} + +/// Test the selection of a random quote from the Quotes struct. +#[test] +fn test_random_quote_selection() { + let quotes_vec = vec![ + Quote { + quote_text: "Test quote 1".to_string(), + author: "Author 1".to_string(), + date_added: "2024-01-01".to_string(), + image_url: "http://example.com/image1.jpg".to_string(), + }, + // ... more quotes ... + ]; + + let mut quotes = Quotes::new(quotes_vec); + + let selected_quote_text = match quotes.select_random_quote() { + Ok(quote) => quote.quote_text.clone(), + Err(e) => panic!("Failed to select a random quote: {}", e), + }; + + let quotes_texts: HashSet<_> = quotes.quotes.iter().map(|q| &q.quote_text).collect(); + + assert!(quotes_texts.contains(&selected_quote_text)); +} + +/// Test the selection of all quotes from the Quotes struct. +#[test] +fn test_all_quotes_selection() { + let quotes_vec = vec![ + Quote { + quote_text: "Test quote 1".to_string(), + author: "Author 1".to_string(), + date_added: "2024-01-01".to_string(), + image_url: "http://example.com/image1.jpg".to_string(), + }, + //... more quotes... + Quote { + quote_text: "Test quote 2".to_string(), + author: "Author 2".to_string(), + date_added: "2024-01-02".to_string(), + image_url: "http://example.com/image2.jpg".to_string(), + }, + ]; + let quotes = Quotes::new(quotes_vec.clone()); + let all_quotes = match quotes.select_all_quotes() { + Ok(quotes) => quotes, + Err(e) => panic!("Failed to select all quotes: {}", e), + }; + assert_eq!(all_quotes.len(), quotes_vec.len()); + assert_eq!(all_quotes[0].quote_text, quotes_vec[0].quote_text); + assert_eq!(all_quotes[1].quote_text, quotes_vec[1].quote_text); + assert_eq!(all_quotes[0].author, quotes_vec[0].author); + assert_eq!(all_quotes[1].author, quotes_vec[1].author); + assert_eq!(all_quotes[0].date_added, quotes_vec[0].date_added); + assert_eq!(all_quotes[1].date_added, quotes_vec[1].date_added); + assert_eq!(all_quotes[0].image_url, quotes_vec[0].image_url); + assert_eq!(all_quotes[1].image_url, quotes_vec[1].image_url); +} + +/// Test the equality and inequality of Quote structs. +#[test] +fn test_quote_equality() { + let quote1 = Quote { + quote_text: "Same quote".to_string(), + author: "Same author".to_string(), + date_added: "2024-01-21".to_string(), + image_url: "http://example.com/image.jpg".to_string(), + }; + + let quote2 = quote1.clone(); + + assert_eq!(quote1, quote2); + + let quote3 = Quote { + quote_text: "Different quote".to_string(), + // other fields same as quote1 + author: "Same author".to_string(), + date_added: "2024-01-21".to_string(), + image_url: "http://example.com/image.jpg".to_string(), + }; + + assert_ne!(quote1, quote3); +} + +/// Test selecting a random quote when the vector is empty. +#[test] +fn test_select_random_quote_empty_vector() { + let mut quotes = Quotes::new(Vec::new()); + assert!(matches!(quotes.select_random_quote(), Err(_))); +} + +/// Test selecting all quotes when the vector is empty. +#[test] +fn test_select_all_quotes_empty_vector() { + let quotes = Quotes::new(Vec::new()); // empty vector + + match quotes.select_all_quotes() { + Ok(_) => panic!("Expected an error for empty quotes vector, but got Ok"), + Err(e) => assert_eq!(e.to_string(), "No available quotes"), + } +} + +/// Test the serialization and deserialization of Quote structs. +#[test] +fn test_quote_serialization_deserialization() { + let quote = Quote { + quote_text: "Test quote".to_string(), + author: "Test author".to_string(), + date_added: "2024-01-21".to_string(), + image_url: "http://example.com/image.jpg".to_string(), + }; + + let serialized = serde_json::to_string("e).unwrap(); + let deserialized: Quote = serde_json::from_str(&serialized).unwrap(); + + assert_eq!(quote, deserialized); +} + +/// Test the creation of an invalid quote with empty fields. +#[test] +fn test_invalid_quote_creation() { + let quote = Quote { + quote_text: "".to_string(), + author: "".to_string(), + date_added: "2024-01-21".to_string(), + image_url: "http://example.com/image.jpg".to_string(), + }; + + assert_eq!(quote.quote_text, ""); + assert_eq!(quote.author, ""); +} diff --git a/tests/test_sitemap.rs b/tests/test_sitemap.rs new file mode 100644 index 0000000..c8ab926 --- /dev/null +++ b/tests/test_sitemap.rs @@ -0,0 +1,26 @@ +// Copyright notice and licensing information. +// Copyright © 2024 The Wiser One. All rights reserved. +// SPDX-License-Identifier: MIT OR Apache-2.0 + +#[cfg(test)] +mod tests { + use wiserone::sitemap::generate_sitemap_file; + use std::fs; + use std::error::Error; + + #[test] + fn test_generate_sitemap_file_no_html_files() -> Result<(), Box> { + // Ensure the docs directory is empty + fs::remove_dir_all("./docs")?; + fs::create_dir("./docs")?; + + // Expect an empty sitemap to be generated + generate_sitemap_file("https://example.com/docs/")?; + + let sitemap_content = fs::read_to_string("./docs/sitemap.xml")?; + assert!(sitemap_content.contains("")); + + Ok(()) + } +} From ac1cbaa2eb971ddbe339f7161a6afcfe2fbdf12d Mon Sep 17 00:00:00 2001 From: Sebastien Rousseau Date: Sun, 21 Jan 2024 21:33:17 +0000 Subject: [PATCH 2/2] fix(wiserone): :ambulance: minor test fix --- docs/sitemap.xml | 64 ++++++++++++++++++++++---------------------- tests/test_quotes.rs | 2 +- 2 files changed, 33 insertions(+), 33 deletions(-) diff --git a/docs/sitemap.xml b/docs/sitemap.xml index 67eb158..2b075b6 100644 --- a/docs/sitemap.xml +++ b/docs/sitemap.xml @@ -3,161 +3,161 @@ https://wiserone.com/2024_01_18.html weekly - 2024-01-21 21:25:51.211284 +00:00:00 + 2024-01-21 21:31:41.159367 +00:00:00 https://wiserone.com/2024_01_22.html weekly - 2024-01-21 21:25:51.211284 +00:00:00 + 2024-01-21 21:31:41.159367 +00:00:00 https://wiserone.com/2024_01_02.html weekly - 2024-01-21 21:25:51.211284 +00:00:00 + 2024-01-21 21:31:41.159367 +00:00:00 https://wiserone.com/2024_01_14.html weekly - 2024-01-21 21:25:51.211284 +00:00:00 + 2024-01-21 21:31:41.159367 +00:00:00 https://wiserone.com/index.html weekly - 2024-01-21 21:25:51.211284 +00:00:00 + 2024-01-21 21:31:41.159367 +00:00:00 https://wiserone.com/2024_01_15.html weekly - 2024-01-21 21:25:51.211284 +00:00:00 + 2024-01-21 21:31:41.159367 +00:00:00 https://wiserone.com/2024_01_03.html weekly - 2024-01-21 21:25:51.211284 +00:00:00 + 2024-01-21 21:31:41.159367 +00:00:00 https://wiserone.com/2024_01_23.html weekly - 2024-01-21 21:25:51.211284 +00:00:00 + 2024-01-21 21:31:41.159367 +00:00:00 https://wiserone.com/2024_01_19.html weekly - 2024-01-21 21:25:51.211284 +00:00:00 + 2024-01-21 21:31:41.159367 +00:00:00 https://wiserone.com/2024_01_04.html weekly - 2024-01-21 21:25:51.211284 +00:00:00 + 2024-01-21 21:31:41.159367 +00:00:00 https://wiserone.com/2024_01_12.html weekly - 2024-01-21 21:25:51.211284 +00:00:00 + 2024-01-21 21:31:41.159367 +00:00:00 https://wiserone.com/2024_01_28.html weekly - 2024-01-21 21:25:51.211284 +00:00:00 + 2024-01-21 21:31:41.159367 +00:00:00 https://wiserone.com/2024_01_08.html weekly - 2024-01-21 21:25:51.211284 +00:00:00 + 2024-01-21 21:31:41.159367 +00:00:00 https://wiserone.com/2024_01_24.html weekly - 2024-01-21 21:25:51.211284 +00:00:00 + 2024-01-21 21:31:41.159367 +00:00:00 https://wiserone.com/2024_01_25.html weekly - 2024-01-21 21:25:51.211284 +00:00:00 + 2024-01-21 21:31:41.159367 +00:00:00 https://wiserone.com/2024_01_09.html weekly - 2024-01-21 21:25:51.211284 +00:00:00 + 2024-01-21 21:31:41.159367 +00:00:00 https://wiserone.com/2024_01_29.html weekly - 2024-01-21 21:25:51.211284 +00:00:00 + 2024-01-21 21:31:41.159367 +00:00:00 https://wiserone.com/2024_01_13.html weekly - 2024-01-21 21:25:51.211284 +00:00:00 + 2024-01-21 21:31:41.159367 +00:00:00 https://wiserone.com/2024_01_05.html weekly - 2024-01-21 21:25:51.211284 +00:00:00 + 2024-01-21 21:31:41.159367 +00:00:00 https://wiserone.com/2024_01_10.html weekly - 2024-01-21 21:25:51.211284 +00:00:00 + 2024-01-21 21:31:41.159367 +00:00:00 https://wiserone.com/2024_01_06.html weekly - 2024-01-21 21:25:51.211284 +00:00:00 + 2024-01-21 21:31:41.159367 +00:00:00 https://wiserone.com/2024_01_26.html weekly - 2024-01-21 21:25:51.211284 +00:00:00 + 2024-01-21 21:31:41.159367 +00:00:00 https://wiserone.com/2024_01_30.html weekly - 2024-01-21 21:25:51.211284 +00:00:00 + 2024-01-21 21:31:41.159367 +00:00:00 https://wiserone.com/2024_01_31.html weekly - 2024-01-21 21:25:51.211284 +00:00:00 + 2024-01-21 21:31:41.159367 +00:00:00 https://wiserone.com/2024_01_27.html weekly - 2024-01-21 21:25:51.211284 +00:00:00 + 2024-01-21 21:31:41.159367 +00:00:00 https://wiserone.com/2024_01_07.html weekly - 2024-01-21 21:25:51.211284 +00:00:00 + 2024-01-21 21:31:41.159367 +00:00:00 https://wiserone.com/2024_01_11.html weekly - 2024-01-21 21:25:51.211284 +00:00:00 + 2024-01-21 21:31:41.159367 +00:00:00 https://wiserone.com/2024_01_20.html weekly - 2024-01-21 21:25:51.211284 +00:00:00 + 2024-01-21 21:31:41.159367 +00:00:00 https://wiserone.com/2024_01_16.html weekly - 2024-01-21 21:25:51.211284 +00:00:00 + 2024-01-21 21:31:41.159367 +00:00:00 https://wiserone.com/2024_01_01.html weekly - 2024-01-21 21:25:51.211284 +00:00:00 + 2024-01-21 21:31:41.159367 +00:00:00 https://wiserone.com/2024_01_17.html weekly - 2024-01-21 21:25:51.211284 +00:00:00 + 2024-01-21 21:31:41.159367 +00:00:00 https://wiserone.com/2024_01_21.html weekly - 2024-01-21 21:25:51.211284 +00:00:00 + 2024-01-21 21:31:41.159367 +00:00:00 \ No newline at end of file diff --git a/tests/test_quotes.rs b/tests/test_quotes.rs index 6b30b96..ca7b758 100644 --- a/tests/test_quotes.rs +++ b/tests/test_quotes.rs @@ -131,7 +131,7 @@ fn test_quote_equality() { #[test] fn test_select_random_quote_empty_vector() { let mut quotes = Quotes::new(Vec::new()); - assert!(matches!(quotes.select_random_quote(), Err(_))); + assert!(quotes.select_random_quote().is_err()); } /// Test selecting all quotes when the vector is empty.