Skip to content

Commit

Permalink
Merge pull request #45 from sinproject-iwasaki/44-validator-value-obj…
Browse files Browse the repository at this point in the history
…ect-and-rstest

Validator, Value Object, and rstest #44
  • Loading branch information
sinproject-iwasaki authored Mar 6, 2024
2 parents 93c90fe + 2991eea commit 480f37d
Show file tree
Hide file tree
Showing 5 changed files with 170 additions and 36 deletions.
126 changes: 103 additions & 23 deletions src/config.rs
Original file line number Diff line number Diff line change
@@ -1,55 +1,135 @@
use crate::constants::{UNIT_LENGTH, UNIT_SIZE, WINDOW_TITLE};
use crate::validator;

pub struct Title(String);

impl Title {
pub fn new(title: &str) -> Result<Self, String> {
validator::validate_string_length(title, 1, 50)?;
Ok(Self(title.to_string()))
}

pub fn value(&self) -> &str {
&self.0
}
}

pub struct Width(u32);

impl Width {
pub fn new(width: u32) -> Result<Self, String> {
validator::validate_numeric_range(width, 1, 1000)?;
Ok(Self(width))
}

pub fn value(&self) -> u32 {
self.0
}
}

pub struct Height(u32);

impl Height {
pub fn new(height: u32) -> Result<Self, String> {
validator::validate_numeric_range(height, 1, 1000)?;
Ok(Self(height))
}

pub fn value(&self) -> u32 {
self.0
}
}

pub struct WindowConfig {
pub title: String,
pub width: u32,
pub height: u32,
pub title: Title,
pub width: Width,
pub height: Height,
}

impl WindowConfig {
pub fn new(title: String, width: u32, height: u32) -> WindowConfig {
Self {
title,
width,
height,
}
pub fn new(title: &str, width: u32, height: u32) -> Result<WindowConfig, String> {
Ok(Self {
title: Title::new(title)?,
width: Width::new(width)?,
height: Height::new(height)?,
})
}

fn calculate_window_size() -> (u32, u32) {
(UNIT_SIZE.0 * UNIT_LENGTH.0, UNIT_SIZE.1 * UNIT_LENGTH.1)
}

fn create_with_default_size(title: &str) -> WindowConfig {
fn create_with_default_size(title: &str) -> Result<WindowConfig, String> {
let (width, height) = Self::calculate_window_size();
Self::new(title.to_string(), width, height)
Self::new(title, width, height)
}
}

pub fn create_window_config() -> WindowConfig {
pub fn create_window_config() -> Result<WindowConfig, String> {
WindowConfig::create_with_default_size(WINDOW_TITLE)
}

#[cfg(test)]
mod tests {
use super::*;
use rstest::rstest;

#[test]
fn test_window_config_creation() {
let title = "Test Window".to_string();
let width = 800;
let height = 600;
let window_config = WindowConfig::new(title.clone(), width, height);
#[rstest]
#[case::min_1("T")]
#[case::max_50("12345678901234567890123456789012345678901234567890")]
#[case::normal("Test Window")]
#[should_panic]
#[case::min_0("")]
#[should_panic]
#[case::max_51("123456789012345678901234567890123456789012345678901")]
fn test_title_new(#[case] title: &str) {
assert!(Title::new(title).is_ok());
}

#[rstest]
#[case::min_1(1)]
#[case::max_1000(1000)]
#[case::normal(50)]
#[should_panic]
#[case::min_0(0)]
#[should_panic]
#[case::max_1001(1001)]
fn test_width_new(#[case] width: u32) {
assert!(Width::new(width).is_ok());
}

#[rstest]
#[case::min_1(1)]
#[case::max_1000(1000)]
#[case::normal(50)]
#[should_panic]
#[case::min_0(0)]
#[should_panic]
#[case::max_1001(1001)]
fn test_height_new(#[case] height: u32) {
assert!(Height::new(height).is_ok());
}

#[rstest]
#[case::normal("Test Window", 800, 600)]
#[case::min_1("T", 1, 1)]
#[case::max_1000("12345678901234567890123456789012345678901234567890", 1000, 1000)]
fn test_window_config_creation(#[case] title: &str, #[case] width: u32, #[case] height: u32) {
let window_config = WindowConfig::new(title, width, height).unwrap();

assert_eq!(window_config.title, title);
assert_eq!(window_config.width, width);
assert_eq!(window_config.height, height);
assert_eq!(window_config.title.value(), title);
assert_eq!(window_config.width.value(), width);
assert_eq!(window_config.height.value(), height);
}

#[test]
fn test_default_window_size() {
let window_config = WindowConfig::create_with_default_size("Default Size Window");
let window_config = WindowConfig::create_with_default_size("Default Size Window").unwrap();
let expected_size = WindowConfig::calculate_window_size();

assert_eq!((window_config.width, window_config.height), expected_size);
assert_eq!(
(window_config.width.value(), window_config.height.value()),
expected_size
);
}
}
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ mod sprite;
mod text;
mod text_resources;
mod utils;
mod validator;
mod window;

pub fn run() {
Expand Down
16 changes: 9 additions & 7 deletions src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,19 @@ pub fn unit_size() -> Vec2 {
#[cfg(test)]
mod tests {
use super::*;
use rstest::rstest;

#[test]
fn test_vec2_from_tuple() {
let tuple = (100, 50);
let result = vec2_from_tuple(tuple);
assert_eq!(result, Vec2::new(100.0, 50.0));
#[rstest]
#[case::tuple((100, 50), Vec2::new(100.0, 50.0))]
#[case::tuple((200, 100), Vec2::new(200.0, 100.0))]
fn test_vec2_from_tuple(#[case] tuple: (u32, u32), #[case] expected: Vec2) {
let actual = vec2_from_tuple(tuple);
assert_eq!(actual, expected);
}

#[test]
fn test_unit_size() {
let result = unit_size();
assert_eq!(result, vec2_from_tuple(constants::UNIT_SIZE));
let actual = unit_size();
assert_eq!(actual, vec2_from_tuple(constants::UNIT_SIZE));
}
}
51 changes: 51 additions & 0 deletions src/validator.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
pub fn validate_string_length(value: &str, min: usize, max: usize) -> Result<(), String> {
if (min..=max).contains(&value.len()) {
Ok(())
} else {
Err(format!(
"Value must be between {} and {} characters long: {}",
min,
max,
value.len()
))
}
}

pub fn validate_numeric_range(value: u32, min: u32, max: u32) -> Result<(), String> {
if (min..=max).contains(&value) {
Ok(())
} else {
Err(format!(
"Value must be between {} and {}: {}",
min, max, value
))
}
}

#[cfg(test)]
mod test {
use super::*;
use rstest::rstest;

#[rstest]
#[case::min_1("T", 1, 10)]
#[case::max_50("12345678901234567890123456789012345678901234567890", 1, 50)]
#[should_panic]
#[case::min_1_empty("", 1, 10)]
#[should_panic]
#[case::max_50_over("123456789012345678901234567890123456789012345678901", 1, 50)]
fn test_validate_string_length(#[case] value: &str, #[case] min: usize, #[case] max: usize) {
assert!(validate_string_length(value, min, max).is_ok());
}

#[rstest]
#[case::min_1(1, 1, 10)]
#[case::max_50(50, 1, 50)]
#[should_panic]
#[case::min_0(0, 1, 10)]
#[should_panic]
#[case::max_51(51, 1, 50)]
fn test_validate_numeric_range(#[case] value: u32, #[case] min: u32, #[case] max: u32) {
assert!(validate_numeric_range(value, min, max).is_ok());
}
}
12 changes: 6 additions & 6 deletions src/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,21 @@ use bevy::prelude::*;

use crate::{config, utils::unit_size};

fn create_window(title: String, width: u32, height: u32) -> Window {
fn create_window(title: &str, width: u32, height: u32) -> Window {
Window {
title,
title: title.to_string(),
resolution: (width as f32, height as f32).into(),
..default()
}
}

pub fn init_window() -> Window {
let window_config = config::create_window_config();
let window_config = config::create_window_config().unwrap();

create_window(
window_config.title,
window_config.width,
window_config.height,
window_config.title.value(),
window_config.width.value(),
window_config.height.value(),
)
}

Expand Down

0 comments on commit 480f37d

Please sign in to comment.