use lyrical_meter::*;
use rand_construct::*;
use ai_descriptor::*;
use rand::rngs::StdRng;
use rand::SeedableRng;
use serde_json;
#[test]
fn test_metrical_foot_distribution() {
let mut rng = StdRng::seed_from_u64(42);
let foot = MetricalFoot::random_with_rng(&mut rng);
assert!(matches!(
foot,
MetricalFoot::Iamb
| MetricalFoot::Trochee
| MetricalFoot::Anapest
| MetricalFoot::Dactyl
| MetricalFoot::Spondee
| MetricalFoot::Pyrrhic
| MetricalFoot::Amphibrach
| MetricalFoot::Amphimacer
| MetricalFoot::Bacchic
| MetricalFoot::Cretic
| MetricalFoot::Antibacchius
| MetricalFoot::Molossus
| MetricalFoot::Tribrach
| MetricalFoot::Choriamb
| MetricalFoot::IonicAMinore
| MetricalFoot::IonicAMajore
| MetricalFoot::Aeolic
));
}
#[test]
fn test_metrical_foot_ai_descriptor() {
let foot = MetricalFoot::Iamb;
assert_eq!(
foot.text(),
"Uses iambic meter, with unstressed-stressed syllables."
);
}
#[test]
fn test_line_length_distribution() {
let mut rng = StdRng::seed_from_u64(42);
let length = LineLength::random_with_rng(&mut rng);
assert!(matches!(
length,
LineLength::Monometer
| LineLength::Dimeter
| LineLength::Trimeter
| LineLength::Tetrameter
| LineLength::Pentameter
| LineLength::Hexameter
| LineLength::Heptameter
| LineLength::Octameter
| LineLength::Nonameter
| LineLength::Decameter
));
}
#[test]
fn test_line_length_ai_descriptor() {
let length = LineLength::Pentameter;
assert_eq!(
length.text(),
"Each line should have five feet (pentameter)."
);
}
#[test]
fn test_other_meter_distribution() {
let mut rng = StdRng::seed_from_u64(42);
let other_meter = OtherMeter::random_with_rng(&mut rng);
assert!(matches!(
other_meter,
OtherMeter::ClimbingRhyme
| OtherMeter::FallingRhyme
| OtherMeter::MixedMeter
| OtherMeter::FreeVerse
| OtherMeter::BlankVerse
));
}
#[test]
fn test_other_meter_ai_descriptor() {
let other_meter = OtherMeter::FreeVerse;
assert_eq!(
other_meter.text(),
"Write in free verse, without a consistent meter or rhyme scheme."
);
}
#[test]
fn test_lyrical_meter_distribution() {
let mut rng = StdRng::seed_from_u64(42);
let lyrical_meter = LyricalMeter::random_with_rng(&mut rng);
assert!(matches!(
lyrical_meter.foot(),
MetricalFoot::Iamb
| MetricalFoot::Trochee
| MetricalFoot::Anapest
| MetricalFoot::Dactyl
| MetricalFoot::Spondee
| MetricalFoot::Pyrrhic
| MetricalFoot::Amphibrach
| MetricalFoot::Amphimacer
| MetricalFoot::Bacchic
| MetricalFoot::Cretic
| MetricalFoot::Antibacchius
| MetricalFoot::Molossus
| MetricalFoot::Tribrach
| MetricalFoot::Choriamb
| MetricalFoot::IonicAMinore
| MetricalFoot::IonicAMajore
| MetricalFoot::Aeolic
));
}
#[test]
fn test_lyrical_meter_ai_descriptor() {
let lyrical_meter = LyricalMeter::builder()
.foot(MetricalFoot::Dactyl)
.length(LineLength::Hexameter)
.build();
let expected = "Uses dactylic meter, with stressed-unstressed-unstressed syllables. Each line should have six feet (hexameter).";
assert_eq!(lyrical_meter.ai_alt(), expected);
}
#[test]
fn test_meter_distribution() {
let mut rng = StdRng::seed_from_u64(42);
let meter = Meter::random_with_rng(&mut rng);
match meter {
Meter::Standard(ref lyrical_meter) => {
assert!(matches!(
lyrical_meter.foot(),
MetricalFoot::Iamb
| MetricalFoot::Trochee
| MetricalFoot::Anapest
| MetricalFoot::Dactyl
| MetricalFoot::Spondee
| MetricalFoot::Pyrrhic
| MetricalFoot::Amphibrach
| MetricalFoot::Amphimacer
| MetricalFoot::Bacchic
| MetricalFoot::Cretic
| MetricalFoot::Antibacchius
| MetricalFoot::Molossus
| MetricalFoot::Tribrach
| MetricalFoot::Choriamb
| MetricalFoot::IonicAMinore
| MetricalFoot::IonicAMajore
| MetricalFoot::Aeolic
));
}
Meter::Other(ref other_meter) => {
assert!(matches!(
other_meter,
OtherMeter::ClimbingRhyme
| OtherMeter::FallingRhyme
| OtherMeter::MixedMeter
| OtherMeter::FreeVerse
| OtherMeter::BlankVerse
));
}
}
}
#[test]
fn test_meter_ai_descriptor() {
let meter = Meter::Other(OtherMeter::BlankVerse);
assert_eq!(
meter.ai(),
"Write in blank verse, using unrhymed iambic pentameter."
);
}
#[test]
fn test_lyrical_meter_builder() {
let lyrical_meter = LyricalMeter::builder()
.foot(MetricalFoot::Anapest)
.length(LineLength::Tetrameter)
.build();
assert_eq!(lyrical_meter.foot(), &MetricalFoot::Anapest);
assert_eq!(lyrical_meter.length(), Some(&LineLength::Tetrameter));
}
#[test]
fn test_lyrical_meter_getters_setters() {
let mut lyrical_meter = LyricalMeter::default();
lyrical_meter.set_foot(MetricalFoot::Trochee);
lyrical_meter.set_length(Some(LineLength::Pentameter));
assert_eq!(lyrical_meter.foot(), &MetricalFoot::Trochee);
assert_eq!(lyrical_meter.length(), Some(&LineLength::Pentameter));
}
#[test]
fn test_meter_builder_standard() {
let meter = Meter::Standard(
LyricalMeter::builder()
.foot(MetricalFoot::Dactyl)
.length(LineLength::Hexameter)
.build(),
);
if let Meter::Standard(ref lyrical_meter) = meter {
assert_eq!(lyrical_meter.foot(), &MetricalFoot::Dactyl);
assert_eq!(lyrical_meter.length(), Some(&LineLength::Hexameter));
} else {
panic!("Expected Meter::Standard variant");
}
}
#[test]
fn test_meter_builder_other() {
let meter = Meter::Other(OtherMeter::FreeVerse);
if let Meter::Other(ref other_meter) = meter {
assert_eq!(other_meter, &OtherMeter::FreeVerse);
} else {
panic!("Expected Meter::Other variant");
}
}
#[test]
fn test_other_meter_methods() {
let other_meter = OtherMeter::FreeVerse;
assert!(other_meter.is_free_verse());
assert!(!other_meter.is_blank_verse());
let other_meter = OtherMeter::BlankVerse;
assert!(other_meter.is_blank_verse());
assert!(!other_meter.is_free_verse());
}
#[test]
fn test_meter_is_same_type() {
let meter1 = Meter::Standard(LyricalMeter::default());
let meter2 = Meter::Other(OtherMeter::MixedMeter);
let meter3 = Meter::Standard(
LyricalMeter::builder()
.foot(MetricalFoot::Trochee)
.build(),
);
assert!(meter1.is_same_type(&meter3));
assert!(!meter1.is_same_type(&meter2));
}
#[test]
fn test_meter_as_standard() {
let meter = Meter::Standard(LyricalMeter::default());
assert!(meter.as_standard().is_some());
assert!(meter.as_other().is_none());
}
#[test]
fn test_meter_as_other() {
let meter = Meter::Other(OtherMeter::FreeVerse);
assert!(meter.as_other().is_some());
assert!(meter.as_standard().is_none());
}
#[test]
fn test_metrical_foot_serialization() {
let foot = MetricalFoot::Iamb;
let serialized = serde_json::to_string(&foot).unwrap();
let deserialized: MetricalFoot = serde_json::from_str(&serialized).unwrap();
assert_eq!(foot, deserialized);
}
#[test]
fn test_line_length_serialization() {
let length = LineLength::Pentameter;
let serialized = serde_json::to_string(&length).unwrap();
let deserialized: LineLength = serde_json::from_str(&serialized).unwrap();
assert_eq!(length, deserialized);
}
#[test]
fn test_other_meter_serialization() {
let other_meter = OtherMeter::FreeVerse;
let serialized = serde_json::to_string(&other_meter).unwrap();
let deserialized: OtherMeter = serde_json::from_str(&serialized).unwrap();
assert_eq!(other_meter, deserialized);
}
#[test]
fn test_lyrical_meter_serialization() {
let lyrical_meter = LyricalMeter::builder()
.foot(MetricalFoot::Dactyl)
.length(LineLength::Hexameter)
.build();
let serialized = serde_json::to_string(&lyrical_meter).unwrap();
let deserialized: LyricalMeter = serde_json::from_str(&serialized).unwrap();
assert_eq!(lyrical_meter, deserialized);
}
#[test]
fn test_meter_serialization() {
let meter = Meter::Other(OtherMeter::BlankVerse);
let serialized = serde_json::to_string(&meter).unwrap();
let deserialized: Meter = serde_json::from_str(&serialized).unwrap();
assert_eq!(meter, deserialized);
let meter = Meter::Standard(
LyricalMeter::builder()
.foot(MetricalFoot::Anapest)
.length(LineLength::Trimeter)
.build(),
);
let serialized = serde_json::to_string(&meter).unwrap();
let deserialized: Meter = serde_json::from_str(&serialized).unwrap();
assert_eq!(meter, deserialized);
}
#[test]
fn test_display_implementations() {
let foot = MetricalFoot::Iamb;
assert_eq!(format!("{:?}", foot), "Iamb");
let length = LineLength::Pentameter;
assert_eq!(format!("{:?}", length), "Pentameter");
let other_meter = OtherMeter::FreeVerse;
assert_eq!(
format!("{}", other_meter.text()),
"Write in free verse, without a consistent meter or rhyme scheme."
);
let lyrical_meter = LyricalMeter::builder()
.foot(MetricalFoot::Dactyl)
.length(LineLength::Hexameter)
.build();
assert_eq!(format!("{}", lyrical_meter.ai_alt()), "Uses dactylic meter, with stressed-unstressed-unstressed syllables. Each line should have six feet (hexameter).");
let meter = Meter::Standard(lyrical_meter);
assert_eq!(format!("{}", meter.ai_alt()), "Uses dactylic meter, with stressed-unstressed-unstressed syllables. Each line should have six feet (hexameter).");
let meter = Meter::Other(OtherMeter::BlankVerse);
assert_eq!(
format!("{}", meter.ai()),
"Write in blank verse, using unrhymed iambic pentameter."
);
}
#[test]
fn test_default_implementations() {
let lyrical_meter = LyricalMeter::default();
assert_eq!(lyrical_meter.foot(), &MetricalFoot::Iamb);
assert_eq!(lyrical_meter.length(), None);
let meter_builder = MeterBuilder::default();
let meter = meter_builder.build();
if let Meter::Standard(ref lyrical_meter) = meter {
assert_eq!(lyrical_meter.foot(), &MetricalFoot::Iamb);
assert_eq!(lyrical_meter.length(), None);
} else {
panic!("Expected Meter::Standard variant");
}
}
#[test]
fn test_random_generation_consistency() {
let mut rng1 = StdRng::seed_from_u64(42);
let mut rng2 = StdRng::seed_from_u64(42);
let foot1 = MetricalFoot::random_with_rng(&mut rng1);
let foot2 = MetricalFoot::random_with_rng(&mut rng2);
assert_eq!(foot1, foot2);
let length1 = LineLength::random_with_rng(&mut rng1);
let length2 = LineLength::random_with_rng(&mut rng2);
assert_eq!(length1, length2);
let other_meter1 = OtherMeter::random_with_rng(&mut rng1);
let other_meter2 = OtherMeter::random_with_rng(&mut rng2);
assert_eq!(other_meter1, other_meter2);
let lyrical_meter1 = LyricalMeter::random_with_rng(&mut rng1);
let lyrical_meter2 = LyricalMeter::random_with_rng(&mut rng2);
assert_eq!(lyrical_meter1, lyrical_meter2);
let meter1 = Meter::random_with_rng(&mut rng1);
let meter2 = Meter::random_with_rng(&mut rng2);
assert_eq!(meter1, meter2);
}
#[test]
fn test_ai_descriptors_not_empty() {
let feet = [
MetricalFoot::Iamb,
MetricalFoot::Trochee,
MetricalFoot::Anapest,
MetricalFoot::Dactyl,
MetricalFoot::Spondee,
MetricalFoot::Pyrrhic,
MetricalFoot::Amphibrach,
MetricalFoot::Amphimacer,
MetricalFoot::Bacchic,
MetricalFoot::Cretic,
MetricalFoot::Antibacchius,
MetricalFoot::Molossus,
MetricalFoot::Tribrach,
MetricalFoot::Choriamb,
MetricalFoot::IonicAMinore,
MetricalFoot::IonicAMajore,
MetricalFoot::Aeolic,
];
for foot in &feet {
assert!(!foot.text().is_empty());
}
let lengths = [
LineLength::Monometer,
LineLength::Dimeter,
LineLength::Trimeter,
LineLength::Tetrameter,
LineLength::Pentameter,
LineLength::Hexameter,
LineLength::Heptameter,
LineLength::Octameter,
LineLength::Nonameter,
LineLength::Decameter,
];
for length in &lengths {
assert!(!length.text().is_empty());
}
let other_meters = [
OtherMeter::ClimbingRhyme,
OtherMeter::FallingRhyme,
OtherMeter::MixedMeter,
OtherMeter::FreeVerse,
OtherMeter::BlankVerse,
];
for other_meter in &other_meters {
assert!(!other_meter.text().is_empty());
}
}
#[test]
fn test_meter_equality() {
let meter1 = Meter::Standard(
LyricalMeter::builder()
.foot(MetricalFoot::Iamb)
.length(LineLength::Pentameter)
.build(),
);
let meter2 = Meter::Standard(
LyricalMeter::builder()
.foot(MetricalFoot::Iamb)
.length(LineLength::Pentameter)
.build(),
);
let meter3 = Meter::Other(OtherMeter::FreeVerse);
assert_eq!(meter1, meter2);
assert_ne!(meter1, meter3);
}
#[test]
fn test_lyrical_meter_equality() {
let lyrical_meter1 = LyricalMeter::builder()
.foot(MetricalFoot::Trochee)
.length(LineLength::Tetrameter)
.build();
let lyrical_meter2 = LyricalMeter::builder()
.foot(MetricalFoot::Trochee)
.length(LineLength::Tetrameter)
.build();
let lyrical_meter3 = LyricalMeter::builder()
.foot(MetricalFoot::Anapest)
.length(LineLength::Trimeter)
.build();
assert_eq!(lyrical_meter1, lyrical_meter2);
assert_ne!(lyrical_meter1, lyrical_meter3);
}
#[test]
fn test_meter_builder_defaults() {
let meter = MeterBuilder::default().build();
if let Meter::Standard(ref lyrical_meter) = meter {
assert_eq!(lyrical_meter.foot(), &MetricalFoot::Iamb);
assert_eq!(lyrical_meter.length(), None);
} else {
panic!("Expected Meter::Standard variant");
}
}
#[test]
fn test_builder_chain_methods() {
let lyrical_meter = LyricalMeter::builder()
.foot(MetricalFoot::Anapest)
.length(LineLength::Trimeter)
.build();
assert_eq!(lyrical_meter.foot(), &MetricalFoot::Anapest);
assert_eq!(lyrical_meter.length(), Some(&LineLength::Trimeter));
}