Fixed missing validation for given day or task in benchmakr files
This commit is contained in:
parent
603ee1827d
commit
cf604ff98b
15 changed files with 196 additions and 35 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -10,6 +10,7 @@ dependencies = [
|
||||||
"clap",
|
"clap",
|
||||||
"derive_more",
|
"derive_more",
|
||||||
"env_logger",
|
"env_logger",
|
||||||
|
"insta",
|
||||||
"log",
|
"log",
|
||||||
"prettytable-rs",
|
"prettytable-rs",
|
||||||
"ron",
|
"ron",
|
||||||
|
|
|
@ -7,3 +7,6 @@ default-members = ["crates/cli"]
|
||||||
[workspace.dependencies]
|
[workspace.dependencies]
|
||||||
derive_more = { version = "1", features = ["full"] }
|
derive_more = { version = "1", features = ["full"] }
|
||||||
thiserror = "1.0.63"
|
thiserror = "1.0.63"
|
||||||
|
insta = "1.39.0"
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@ solutions_advent_of_code_2023 = { path = "../solutions" }
|
||||||
|
|
||||||
derive_more = { workspace = true }
|
derive_more = { workspace = true }
|
||||||
thiserror = { workspace = true }
|
thiserror = { workspace = true }
|
||||||
|
|
||||||
serde = { version = "1.0.209", features = ["derive"] }
|
serde = { version = "1.0.209", features = ["derive"] }
|
||||||
|
|
||||||
clap = { version = "4.5.15", features = ["derive"] }
|
clap = { version = "4.5.15", features = ["derive"] }
|
||||||
|
@ -16,3 +17,6 @@ log = "0.4.22"
|
||||||
anyhow = "1.0.86"
|
anyhow = "1.0.86"
|
||||||
ron = "0.8.1"
|
ron = "0.8.1"
|
||||||
prettytable-rs = "0.10.0"
|
prettytable-rs = "0.10.0"
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
insta = { workspace = true }
|
||||||
|
|
|
@ -11,7 +11,7 @@ mod row_building;
|
||||||
use crate::{
|
use crate::{
|
||||||
cli::BenchmarkCli,
|
cli::BenchmarkCli,
|
||||||
solving_given::{solve_given, NoSolutionFound},
|
solving_given::{solve_given, NoSolutionFound},
|
||||||
AppError, AppResult,
|
AppResult,
|
||||||
};
|
};
|
||||||
use anyhow::anyhow;
|
use anyhow::anyhow;
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
|
@ -59,27 +59,30 @@ fn solve_and_keep_track_of_runtime(
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_benchmarks(args: &BenchmarkCli) -> AppResult<Vec<(FileToBenchmark, String)>> {
|
fn load_benchmarks(args: &BenchmarkCli) -> AppResult<Vec<(FileToBenchmark, String)>> {
|
||||||
args.files()
|
let mut parsed_benchmarks = Vec::new();
|
||||||
.iter()
|
for next_paths in args.files() {
|
||||||
.flat_map(|path| {
|
let content = std::fs::read_to_string(next_paths).map_err(|error| {
|
||||||
let content = std::fs::read_to_string(path).map_err(|error| {
|
anyhow!(
|
||||||
anyhow!(
|
"Could not read benchmark file at {:?}\n\
|
||||||
"Could not read benchmark file at {:?}\n\
|
|
||||||
Details: {}",
|
Details: {}",
|
||||||
path,
|
next_paths,
|
||||||
error
|
error
|
||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
let parsed: Vec<FileToBenchmark> = ron::from_str(&content).map_err(|error| {
|
let parsed: Vec<FileToBenchmark> = ron::from_str(&content).map_err(|error| {
|
||||||
anyhow!(
|
dbg!();
|
||||||
"Content of benchmark file at ({:?}) is in an invalid ron format\n\
|
anyhow!(
|
||||||
|
"Content of benchmark file at ({:?}) is in an invalid ron format\n\
|
||||||
Details of invalid format: {}",
|
Details of invalid format: {}",
|
||||||
path,
|
next_paths,
|
||||||
error
|
error
|
||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
Ok::<_, AppError>(parsed)
|
parsed_benchmarks.push(parsed);
|
||||||
})
|
}
|
||||||
|
|
||||||
|
parsed_benchmarks
|
||||||
|
.into_iter()
|
||||||
.flatten()
|
.flatten()
|
||||||
.map(|benchmark| {
|
.map(|benchmark| {
|
||||||
let where_to_look = benchmark.where_to_look();
|
let where_to_look = benchmark.where_to_look();
|
||||||
|
|
|
@ -74,3 +74,32 @@ impl FileToBenchmark {
|
||||||
&self.expected_output
|
&self.expected_output
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod testing {
|
||||||
|
|
||||||
|
use ron::error::SpannedResult;
|
||||||
|
|
||||||
|
use crate::benchmarking::FileToBenchmark;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn deserlize_with_error() {
|
||||||
|
const INPUT: &str = include_str!("test_benchmark_with_invalid_day.ron");
|
||||||
|
let actual: SpannedResult<Vec<FileToBenchmark>> = ron::from_str(INPUT);
|
||||||
|
insta::assert_debug_snapshot!(actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn deserlize_with_invalid_task() {
|
||||||
|
const INPUT: &str = include_str!("test_benchmark_with_invalid_task.ron");
|
||||||
|
let actual: SpannedResult<Vec<FileToBenchmark>> = ron::from_str(INPUT);
|
||||||
|
insta::assert_debug_snapshot!(actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn deserlize_with_ron() {
|
||||||
|
const INPUT: &str = include_str!("test_benchmark_as_correct.ron");
|
||||||
|
let actual: SpannedResult<Vec<FileToBenchmark>> = ron::from_str(INPUT);
|
||||||
|
insta::assert_debug_snapshot!(actual);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
---
|
||||||
|
source: crates/cli/src/benchmarking/file_to_benchmark.rs
|
||||||
|
expression: actual
|
||||||
|
---
|
||||||
|
Err(
|
||||||
|
SpannedError {
|
||||||
|
code: Message(
|
||||||
|
"(30) is not within the valid range between 0 and 25",
|
||||||
|
),
|
||||||
|
position: Position {
|
||||||
|
line: 3,
|
||||||
|
col: 22,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
|
@ -0,0 +1,15 @@
|
||||||
|
---
|
||||||
|
source: crates/cli/src/benchmarking/file_to_benchmark.rs
|
||||||
|
expression: actual
|
||||||
|
---
|
||||||
|
Err(
|
||||||
|
SpannedError {
|
||||||
|
code: Message(
|
||||||
|
"(3) is not within the valid range between 1 and 2",
|
||||||
|
),
|
||||||
|
position: Position {
|
||||||
|
line: 4,
|
||||||
|
col: 22,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
|
@ -0,0 +1,28 @@
|
||||||
|
---
|
||||||
|
source: crates/cli/src/benchmarking/file_to_benchmark.rs
|
||||||
|
expression: actual
|
||||||
|
---
|
||||||
|
Ok(
|
||||||
|
[
|
||||||
|
FileToBenchmark {
|
||||||
|
given_day: GivenDay(
|
||||||
|
5,
|
||||||
|
),
|
||||||
|
given_task: GivenTask(
|
||||||
|
2,
|
||||||
|
),
|
||||||
|
where_to_look: "real_puzzel_input/day5_real.txt",
|
||||||
|
expected_output: "42",
|
||||||
|
},
|
||||||
|
FileToBenchmark {
|
||||||
|
given_day: GivenDay(
|
||||||
|
5,
|
||||||
|
),
|
||||||
|
given_task: GivenTask(
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
where_to_look: "real_puzzel_input/day5_real.txt",
|
||||||
|
expected_output: "42",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
)
|
14
crates/cli/src/benchmarking/test_benchmark_as_correct.ron
Normal file
14
crates/cli/src/benchmarking/test_benchmark_as_correct.ron
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
[
|
||||||
|
(
|
||||||
|
given_day: 5,
|
||||||
|
given_task: 2,
|
||||||
|
where_to_look: "real_puzzel_input/day5_real.txt",
|
||||||
|
expected_output: "42",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
given_day: 5,
|
||||||
|
given_task: 1,
|
||||||
|
where_to_look: "real_puzzel_input/day5_real.txt",
|
||||||
|
expected_output: "42",
|
||||||
|
)
|
||||||
|
]
|
|
@ -0,0 +1,14 @@
|
||||||
|
[
|
||||||
|
(
|
||||||
|
given_day: 30,
|
||||||
|
given_task: 2,
|
||||||
|
where_to_look: "real_puzzel_input/day5_real.txt",
|
||||||
|
expected_output: "42",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
given_day: 5,
|
||||||
|
given_task: 1,
|
||||||
|
where_to_look: "real_puzzel_input/day5_real.txt",
|
||||||
|
expected_output: "42",
|
||||||
|
)
|
||||||
|
]
|
|
@ -0,0 +1,14 @@
|
||||||
|
[
|
||||||
|
(
|
||||||
|
given_day: 10,
|
||||||
|
given_task: 3,
|
||||||
|
where_to_look: "real_puzzel_input/day5_real.txt",
|
||||||
|
expected_output: "42",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
given_day: 5,
|
||||||
|
given_task: 1,
|
||||||
|
where_to_look: "real_puzzel_input/day5_real.txt",
|
||||||
|
expected_output: "42",
|
||||||
|
)
|
||||||
|
]
|
|
@ -13,13 +13,25 @@ pub enum InvalidGivenDayError {
|
||||||
constants::MAX_DAY
|
constants::MAX_DAY
|
||||||
)]
|
)]
|
||||||
InvalidFormat(Arc<str>),
|
InvalidFormat(Arc<str>),
|
||||||
#[error("({0}) is within the valid range between 0 and {}", constants::MAX_DAY)]
|
#[error(
|
||||||
|
"({0}) is not within the valid range between 0 and {}",
|
||||||
|
constants::MAX_DAY
|
||||||
|
)]
|
||||||
InvalidRange(u32),
|
InvalidRange(u32),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, Into, PartialEq, Eq, Serialize, Deserialize, Display)]
|
#[derive(Debug, Copy, Clone, Into, PartialEq, Eq, Serialize, Deserialize, Display)]
|
||||||
|
#[serde(try_from = "u32")]
|
||||||
pub struct GivenDay(u32);
|
pub struct GivenDay(u32);
|
||||||
|
|
||||||
|
impl TryFrom<u32> for GivenDay {
|
||||||
|
type Error = InvalidGivenDayError;
|
||||||
|
|
||||||
|
fn try_from(value: u32) -> Result<Self, Self::Error> {
|
||||||
|
Self::new(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl GivenDay {
|
impl GivenDay {
|
||||||
pub fn new(value: u32) -> Result<Self, InvalidGivenDayError> {
|
pub fn new(value: u32) -> Result<Self, InvalidGivenDayError> {
|
||||||
if (1..=constants::MAX_DAY).contains(&value) {
|
if (1..=constants::MAX_DAY).contains(&value) {
|
||||||
|
|
|
@ -13,15 +13,24 @@ pub enum InvalidGivenTaskError {
|
||||||
)]
|
)]
|
||||||
InvalidFormat(Arc<str>),
|
InvalidFormat(Arc<str>),
|
||||||
#[error(
|
#[error(
|
||||||
"({0}) is within the valid range between 1 and {}",
|
"({0}) is not within the valid range between 1 and {}",
|
||||||
constants::MAX_TASK
|
constants::MAX_TASK
|
||||||
)]
|
)]
|
||||||
InvalidRange(u32),
|
InvalidRange(u32),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Copy, Into, Clone, PartialEq, Eq, Serialize, Deserialize, Display)]
|
#[derive(Debug, Copy, Into, Clone, PartialEq, Eq, Serialize, Deserialize, Display)]
|
||||||
|
#[serde(try_from = "u32")]
|
||||||
pub struct GivenTask(u32);
|
pub struct GivenTask(u32);
|
||||||
|
|
||||||
|
impl TryFrom<u32> for GivenTask {
|
||||||
|
type Error = InvalidGivenTaskError;
|
||||||
|
|
||||||
|
fn try_from(value: u32) -> Result<Self, Self::Error> {
|
||||||
|
Self::new(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl GivenTask {
|
impl GivenTask {
|
||||||
pub fn new(value: u32) -> Result<Self, InvalidGivenTaskError> {
|
pub fn new(value: u32) -> Result<Self, InvalidGivenTaskError> {
|
||||||
if (1..=constants::MAX_TASK).contains(&value) {
|
if (1..=constants::MAX_TASK).contains(&value) {
|
||||||
|
|
|
@ -12,4 +12,4 @@ thiserror = { workspace = true }
|
||||||
regex = "1.10.6"
|
regex = "1.10.6"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
insta = "1.39.0"
|
insta = { workspace = true }
|
||||||
|
|
|
@ -1,37 +1,37 @@
|
||||||
[
|
[
|
||||||
(
|
(
|
||||||
given_day: GivenDay(5),
|
given_day: 5,
|
||||||
given_task: GivenTask(2),
|
given_task: 2,
|
||||||
where_to_look: "real_puzzel_input/day5_real.txt",
|
where_to_look: "real_puzzel_input/day5_real.txt",
|
||||||
expected_output: "42",
|
expected_output: "42",
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
given_day: GivenDay(5),
|
given_day: 5,
|
||||||
given_task: GivenTask(1),
|
given_task: 1,
|
||||||
where_to_look: "real_puzzel_input/day5_real.txt",
|
where_to_look: "real_puzzel_input/day5_real.txt",
|
||||||
expected_output: "42",
|
expected_output: "42",
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
given_day: GivenDay(6),
|
given_day: 6,
|
||||||
given_task: GivenTask(1),
|
given_task: 1,
|
||||||
where_to_look: "real_puzzel_input/day6_real.txt",
|
where_to_look: "real_puzzel_input/day6_real.txt",
|
||||||
expected_output: "42",
|
expected_output: "42",
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
given_day: GivenDay(6),
|
given_day: 6,
|
||||||
given_task: GivenTask(2),
|
given_task: 2,
|
||||||
where_to_look: "real_puzzel_input/day6_real.txt",
|
where_to_look: "real_puzzel_input/day6_real.txt",
|
||||||
expected_output: "42",
|
expected_output: "42",
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
given_day: GivenDay(7),
|
given_day: 7,
|
||||||
given_task: GivenTask(1),
|
given_task: 1,
|
||||||
where_to_look: "real_puzzel_input/day7_real.txt",
|
where_to_look: "real_puzzel_input/day7_real.txt",
|
||||||
expected_output: "42",
|
expected_output: "42",
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
given_day: GivenDay(7),
|
given_day: 7,
|
||||||
given_task: GivenTask(2),
|
given_task: 2,
|
||||||
where_to_look: "real_puzzel_input/day7_real.txt",
|
where_to_look: "real_puzzel_input/day7_real.txt",
|
||||||
expected_output: "42",
|
expected_output: "42",
|
||||||
),
|
),
|
||||||
|
|
Loading…
Add table
Reference in a new issue