From ce6297b3dedad050ef11301b1fcfe33e65b91681 Mon Sep 17 00:00:00 2001 From: phenylshima <49227365+femshima@users.noreply.github.com> Date: Sat, 24 Feb 2024 02:34:39 +0900 Subject: [PATCH] Add test for full-context label and text analyzer (#750) * add test for full-context label and text analyzer * reduce number of lines by wrapping MoraModel::new * rename `mora_model` to `mora` --- Cargo.lock | 13 + Cargo.toml | 1 + crates/voicevox_core/Cargo.toml | 1 + .../src/engine/full_context_label.rs | 263 ++++++++++++++++++ crates/voicevox_core/src/engine/model.rs | 4 +- crates/voicevox_core/src/lib.rs | 5 + 6 files changed, 285 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5cae922ff..2ecd9e6ea 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3206,6 +3206,18 @@ dependencies = [ "syn 1.0.102", ] +[[package]] +name = "rstest_reuse" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88530b681abe67924d42cca181d070e3ac20e0740569441a9e35a7cedd2b34a4" +dependencies = [ + "quote", + "rand 0.8.5", + "rustc_version 0.4.0", + "syn 2.0.38", +] + [[package]] name = "rustc-demangle" version = "0.1.21" @@ -4359,6 +4371,7 @@ dependencies = [ "rayon", "regex", "rstest", + "rstest_reuse", "serde", "serde_json", "tempfile", diff --git a/Cargo.toml b/Cargo.toml index 8500292a4..e1f5ecfba 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -62,6 +62,7 @@ rayon = "1.6.1" regex = "1.10.0" reqwest = { version = "0.11.13", default-features = false } rstest = "0.15.0" +rstest_reuse = "0.6.0" serde = "1.0.145" serde_json = "1.0.85" serde_with = "3.3.0" diff --git a/crates/voicevox_core/Cargo.toml b/crates/voicevox_core/Cargo.toml index 36d501b06..1bb228e16 100644 --- a/crates/voicevox_core/Cargo.toml +++ b/crates/voicevox_core/Cargo.toml @@ -45,6 +45,7 @@ zip.workspace = true heck.workspace = true pretty_assertions.workspace = true rstest.workspace = true +rstest_reuse.workspace = true test_util.workspace = true tokio = { workspace = true, features = ["rt", "macros"] } diff --git a/crates/voicevox_core/src/engine/full_context_label.rs b/crates/voicevox_core/src/engine/full_context_label.rs index 79928d246..edda52394 100644 --- a/crates/voicevox_core/src/engine/full_context_label.rs +++ b/crates/voicevox_core/src/engine/full_context_label.rs @@ -338,3 +338,266 @@ impl Utterance { }) } } + +#[cfg(test)] +mod tests { + use rstest_reuse::*; + + use ::test_util::OPEN_JTALK_DIC_DIR; + use rstest::rstest; + + use crate::{ + engine::{open_jtalk::FullcontextExtractor, MoraModel}, + text_analyzer::{OpenJTalkAnalyzer, TextAnalyzer}, + AccentPhraseModel, + }; + + fn mora(text: &str, consonant: Option<&str>, vowel: &str) -> MoraModel { + MoraModel::new( + text.into(), + consonant.map(|c| c.into()), + consonant.and(Some(0.0)), + vowel.into(), + 0.0, + 0.0, + ) + } + + #[template] + #[rstest] + #[case( + "いぇ", + &[ + "xx^xx-sil+y=e/A:xx+xx+xx/B:xx-xx_xx/C:xx_xx+xx/D:xx+xx_xx/E:xx_xx!xx_xx-xx/F:xx_xx#xx_xx@xx_xx|xx_xx/G:1_1%0_xx_xx/H:xx_xx/I:xx-xx@xx+xx&xx-xx|xx+xx/J:1_1/K:1+1-1", + "xx^sil-y+e=sil/A:0+1+1/B:xx-xx_xx/C:09_xx+xx/D:xx+xx_xx/E:xx_xx!xx_xx-xx/F:1_1#0_xx@1_1|1_1/G:xx_xx%xx_xx_xx/H:xx_xx/I:1-1@1+1&1-1|1+1/J:xx_xx/K:1+1-1", + "sil^y-e+sil=xx/A:0+1+1/B:xx-xx_xx/C:09_xx+xx/D:xx+xx_xx/E:xx_xx!xx_xx-xx/F:1_1#0_xx@1_1|1_1/G:xx_xx%xx_xx_xx/H:xx_xx/I:1-1@1+1&1-1|1+1/J:xx_xx/K:1+1-1", + "y^e-sil+xx=xx/A:xx+xx+xx/B:xx-xx_xx/C:xx_xx+xx/D:xx+xx_xx/E:1_1!0_xx-xx/F:xx_xx#xx_xx@xx_xx|xx_xx/G:xx_xx%xx_xx_xx/H:1_1/I:xx-xx@xx+xx&xx-xx|xx+xx/J:xx_xx/K:1+1-1", + ], + &[ + AccentPhraseModel::new( + vec![mora("イェ", Some("y"), "e")], + 1, + None, + false, + ) + ] + )] + #[case( + "んーっ", + &[ + "xx^xx-sil+N=N/A:xx+xx+xx/B:xx-xx_xx/C:xx_xx+xx/D:09+xx_xx/E:xx_xx!xx_xx-xx/F:xx_xx#xx_xx@xx_xx|xx_xx/G:3_3%0_xx_xx/H:xx_xx/I:xx-xx@xx+xx&xx-xx|xx+xx/J:1_3/K:1+1-3", + "xx^sil-N+N=cl/A:-2+1+3/B:xx-xx_xx/C:09_xx+xx/D:09+xx_xx/E:xx_xx!xx_xx-xx/F:3_3#0_xx@1_1|1_3/G:xx_xx%xx_xx_xx/H:xx_xx/I:1-3@1+1&1-1|1+3/J:xx_xx/K:1+1-3", + "sil^N-N+cl=sil/A:-1+2+2/B:xx-xx_xx/C:09_xx+xx/D:09+xx_xx/E:xx_xx!xx_xx-xx/F:3_3#0_xx@1_1|1_3/G:xx_xx%xx_xx_xx/H:xx_xx/I:1-3@1+1&1-1|1+3/J:xx_xx/K:1+1-3", + "N^N-cl+sil=xx/A:0+3+1/B:09-xx_xx/C:09_xx+xx/D:xx+xx_xx/E:xx_xx!xx_xx-xx/F:3_3#0_xx@1_1|1_3/G:xx_xx%xx_xx_xx/H:xx_xx/I:1-3@1+1&1-1|1+3/J:xx_xx/K:1+1-3", + "N^cl-sil+xx=xx/A:xx+xx+xx/B:09-xx_xx/C:xx_xx+xx/D:xx+xx_xx/E:3_3!0_xx-xx/F:xx_xx#xx_xx@xx_xx|xx_xx/G:xx_xx%xx_xx_xx/H:1_3/I:xx-xx@xx+xx&xx-xx|xx+xx/J:xx_xx/K:1+1-3", + ], + &[ + AccentPhraseModel::new( + vec![ + mora("ン", None, "N"), + mora("ン", None, "N"), + mora("ッ", None, "cl"), + ], + 3, + None, + false, + ), + ] + )] + #[case( + "これはテストです", + &[ + "xx^xx-sil+k=o/A:xx+xx+xx/B:xx-xx_xx/C:xx_xx+xx/D:04+xx_xx/E:xx_xx!xx_xx-xx/F:xx_xx#xx_xx@xx_xx|xx_xx/G:3_3%0_xx_xx/H:xx_xx/I:xx-xx@xx+xx&xx-xx|xx+xx/J:2_8/K:1+2-8", + "xx^sil-k+o=r/A:-2+1+3/B:xx-xx_xx/C:04_xx+xx/D:24+xx_xx/E:xx_xx!xx_xx-xx/F:3_3#0_xx@1_2|1_8/G:5_1%0_xx_1/H:xx_xx/I:2-8@1+1&1-2|1+8/J:xx_xx/K:1+2-8", + "sil^k-o+r=e/A:-2+1+3/B:xx-xx_xx/C:04_xx+xx/D:24+xx_xx/E:xx_xx!xx_xx-xx/F:3_3#0_xx@1_2|1_8/G:5_1%0_xx_1/H:xx_xx/I:2-8@1+1&1-2|1+8/J:xx_xx/K:1+2-8", + "k^o-r+e=w/A:-1+2+2/B:xx-xx_xx/C:04_xx+xx/D:24+xx_xx/E:xx_xx!xx_xx-xx/F:3_3#0_xx@1_2|1_8/G:5_1%0_xx_1/H:xx_xx/I:2-8@1+1&1-2|1+8/J:xx_xx/K:1+2-8", + "o^r-e+w=a/A:-1+2+2/B:xx-xx_xx/C:04_xx+xx/D:24+xx_xx/E:xx_xx!xx_xx-xx/F:3_3#0_xx@1_2|1_8/G:5_1%0_xx_1/H:xx_xx/I:2-8@1+1&1-2|1+8/J:xx_xx/K:1+2-8", + "r^e-w+a=t/A:0+3+1/B:04-xx_xx/C:24_xx+xx/D:03+xx_xx/E:xx_xx!xx_xx-xx/F:3_3#0_xx@1_2|1_8/G:5_1%0_xx_1/H:xx_xx/I:2-8@1+1&1-2|1+8/J:xx_xx/K:1+2-8", + "e^w-a+t=e/A:0+3+1/B:04-xx_xx/C:24_xx+xx/D:03+xx_xx/E:xx_xx!xx_xx-xx/F:3_3#0_xx@1_2|1_8/G:5_1%0_xx_1/H:xx_xx/I:2-8@1+1&1-2|1+8/J:xx_xx/K:1+2-8", + "w^a-t+e=s/A:0+1+5/B:24-xx_xx/C:03_xx+xx/D:10+7_2/E:3_3!0_xx-1/F:5_1#0_xx@2_1|4_5/G:xx_xx%xx_xx_xx/H:xx_xx/I:2-8@1+1&1-2|1+8/J:xx_xx/K:1+2-8", + "a^t-e+s=U/A:0+1+5/B:24-xx_xx/C:03_xx+xx/D:10+7_2/E:3_3!0_xx-1/F:5_1#0_xx@2_1|4_5/G:xx_xx%xx_xx_xx/H:xx_xx/I:2-8@1+1&1-2|1+8/J:xx_xx/K:1+2-8", + "t^e-s+U=t/A:1+2+4/B:24-xx_xx/C:03_xx+xx/D:10+7_2/E:3_3!0_xx-1/F:5_1#0_xx@2_1|4_5/G:xx_xx%xx_xx_xx/H:xx_xx/I:2-8@1+1&1-2|1+8/J:xx_xx/K:1+2-8", + "e^s-U+t=o/A:1+2+4/B:24-xx_xx/C:03_xx+xx/D:10+7_2/E:3_3!0_xx-1/F:5_1#0_xx@2_1|4_5/G:xx_xx%xx_xx_xx/H:xx_xx/I:2-8@1+1&1-2|1+8/J:xx_xx/K:1+2-8", + "s^U-t+o=d/A:2+3+3/B:24-xx_xx/C:03_xx+xx/D:10+7_2/E:3_3!0_xx-1/F:5_1#0_xx@2_1|4_5/G:xx_xx%xx_xx_xx/H:xx_xx/I:2-8@1+1&1-2|1+8/J:xx_xx/K:1+2-8", + "U^t-o+d=e/A:2+3+3/B:24-xx_xx/C:03_xx+xx/D:10+7_2/E:3_3!0_xx-1/F:5_1#0_xx@2_1|4_5/G:xx_xx%xx_xx_xx/H:xx_xx/I:2-8@1+1&1-2|1+8/J:xx_xx/K:1+2-8", + "t^o-d+e=s/A:3+4+2/B:03-xx_xx/C:10_7+2/D:xx+xx_xx/E:3_3!0_xx-1/F:5_1#0_xx@2_1|4_5/G:xx_xx%xx_xx_xx/H:xx_xx/I:2-8@1+1&1-2|1+8/J:xx_xx/K:1+2-8", + "o^d-e+s=U/A:3+4+2/B:03-xx_xx/C:10_7+2/D:xx+xx_xx/E:3_3!0_xx-1/F:5_1#0_xx@2_1|4_5/G:xx_xx%xx_xx_xx/H:xx_xx/I:2-8@1+1&1-2|1+8/J:xx_xx/K:1+2-8", + "d^e-s+U=sil/A:4+5+1/B:03-xx_xx/C:10_7+2/D:xx+xx_xx/E:3_3!0_xx-1/F:5_1#0_xx@2_1|4_5/G:xx_xx%xx_xx_xx/H:xx_xx/I:2-8@1+1&1-2|1+8/J:xx_xx/K:1+2-8", + "e^s-U+sil=xx/A:4+5+1/B:03-xx_xx/C:10_7+2/D:xx+xx_xx/E:3_3!0_xx-1/F:5_1#0_xx@2_1|4_5/G:xx_xx%xx_xx_xx/H:xx_xx/I:2-8@1+1&1-2|1+8/J:xx_xx/K:1+2-8", + "s^U-sil+xx=xx/A:xx+xx+xx/B:10-7_2/C:xx_xx+xx/D:xx+xx_xx/E:5_1!0_xx-xx/F:xx_xx#xx_xx@xx_xx|xx_xx/G:xx_xx%xx_xx_xx/H:2_8/I:xx-xx@xx+xx&xx-xx|xx+xx/J:xx_xx/K:1+2-8", + ], + &[ + AccentPhraseModel::new( + vec![ + mora("コ", Some("k"), "o"), + mora("レ", Some("r"), "e"), + mora("ワ", Some("w"), "a"), + ], + 3, + None, + false, + ), + AccentPhraseModel::new( + vec![ + mora("テ", Some("t"), "e"), + mora("ス", Some("s"), "U"), + mora("ト", Some("t"), "o"), + mora("デ", Some("d"), "e"), + mora("ス", Some("s"), "U"), + ], + 1, + None, + false, + ), + ] + )] + #[case( + "1、1000、100万、1億?", + &[ + "xx^xx-sil+i=ch/A:xx+xx+xx/B:xx-xx_xx/C:xx_xx+xx/D:05+xx_xx/E:xx_xx!xx_xx-xx/F:xx_xx#xx_xx@xx_xx|xx_xx/G:2_2%0_xx_xx/H:xx_xx/I:xx-xx@xx+xx&xx-xx|xx+xx/J:1_2/K:4+4-12", + "xx^sil-i+ch=i/A:-1+1+2/B:xx-xx_xx/C:05_xx+xx/D:05+xx_xx/E:xx_xx!xx_xx-xx/F:2_2#0_xx@1_1|1_2/G:2_1%0_xx_0/H:xx_xx/I:1-2@1+4&1-4|1+12/J:1_2/K:4+4-12", + "sil^i-ch+i=pau/A:0+2+1/B:xx-xx_xx/C:05_xx+xx/D:05+xx_xx/E:xx_xx!xx_xx-xx/F:2_2#0_xx@1_1|1_2/G:2_1%0_xx_0/H:xx_xx/I:1-2@1+4&1-4|1+12/J:1_2/K:4+4-12", + "i^ch-i+pau=s/A:0+2+1/B:xx-xx_xx/C:05_xx+xx/D:05+xx_xx/E:xx_xx!xx_xx-xx/F:2_2#0_xx@1_1|1_2/G:2_1%0_xx_0/H:xx_xx/I:1-2@1+4&1-4|1+12/J:1_2/K:4+4-12", + "ch^i-pau+s=e/A:xx+xx+xx/B:05-xx_xx/C:xx_xx+xx/D:05+xx_xx/E:2_2!0_xx-xx/F:xx_xx#xx_xx@xx_xx|xx_xx/G:2_1%0_xx_xx/H:1_2/I:xx-xx@xx+xx&xx-xx|xx+xx/J:1_2/K:4+4-12", + "i^pau-s+e=N/A:0+1+2/B:05-xx_xx/C:05_xx+xx/D:05+xx_xx/E:2_2!0_xx-0/F:2_1#0_xx@1_1|1_2/G:4_3%0_xx_0/H:1_2/I:1-2@2+3&2-3|3+10/J:1_4/K:4+4-12", + "pau^s-e+N=pau/A:0+1+2/B:05-xx_xx/C:05_xx+xx/D:05+xx_xx/E:2_2!0_xx-0/F:2_1#0_xx@1_1|1_2/G:4_3%0_xx_0/H:1_2/I:1-2@2+3&2-3|3+10/J:1_4/K:4+4-12", + "s^e-N+pau=hy/A:1+2+1/B:05-xx_xx/C:05_xx+xx/D:05+xx_xx/E:2_2!0_xx-0/F:2_1#0_xx@1_1|1_2/G:4_3%0_xx_0/H:1_2/I:1-2@2+3&2-3|3+10/J:1_4/K:4+4-12", + "e^N-pau+hy=a/A:xx+xx+xx/B:05-xx_xx/C:xx_xx+xx/D:05+xx_xx/E:2_1!0_xx-xx/F:xx_xx#xx_xx@xx_xx|xx_xx/G:4_3%0_xx_xx/H:1_2/I:xx-xx@xx+xx&xx-xx|xx+xx/J:1_4/K:4+4-12", + "N^pau-hy+a=k/A:-2+1+4/B:05-xx_xx/C:05_xx+xx/D:05+xx_xx/E:2_1!0_xx-0/F:4_3#0_xx@1_1|1_4/G:4_2%1_xx_0/H:1_2/I:1-4@3+2&3-2|5+8/J:1_4/K:4+4-12", + "pau^hy-a+k=u/A:-2+1+4/B:05-xx_xx/C:05_xx+xx/D:05+xx_xx/E:2_1!0_xx-0/F:4_3#0_xx@1_1|1_4/G:4_2%1_xx_0/H:1_2/I:1-4@3+2&3-2|5+8/J:1_4/K:4+4-12", + "hy^a-k+u=m/A:-1+2+3/B:05-xx_xx/C:05_xx+xx/D:05+xx_xx/E:2_1!0_xx-0/F:4_3#0_xx@1_1|1_4/G:4_2%1_xx_0/H:1_2/I:1-4@3+2&3-2|5+8/J:1_4/K:4+4-12", + "a^k-u+m=a/A:-1+2+3/B:05-xx_xx/C:05_xx+xx/D:05+xx_xx/E:2_1!0_xx-0/F:4_3#0_xx@1_1|1_4/G:4_2%1_xx_0/H:1_2/I:1-4@3+2&3-2|5+8/J:1_4/K:4+4-12", + "k^u-m+a=N/A:0+3+2/B:05-xx_xx/C:05_xx+xx/D:05+xx_xx/E:2_1!0_xx-0/F:4_3#0_xx@1_1|1_4/G:4_2%1_xx_0/H:1_2/I:1-4@3+2&3-2|5+8/J:1_4/K:4+4-12", + "u^m-a+N=pau/A:0+3+2/B:05-xx_xx/C:05_xx+xx/D:05+xx_xx/E:2_1!0_xx-0/F:4_3#0_xx@1_1|1_4/G:4_2%1_xx_0/H:1_2/I:1-4@3+2&3-2|5+8/J:1_4/K:4+4-12", + "m^a-N+pau=i/A:1+4+1/B:05-xx_xx/C:05_xx+xx/D:05+xx_xx/E:2_1!0_xx-0/F:4_3#0_xx@1_1|1_4/G:4_2%1_xx_0/H:1_2/I:1-4@3+2&3-2|5+8/J:1_4/K:4+4-12", + "a^N-pau+i=ch/A:xx+xx+xx/B:05-xx_xx/C:xx_xx+xx/D:05+xx_xx/E:4_3!0_xx-xx/F:xx_xx#xx_xx@xx_xx|xx_xx/G:4_2%1_xx_xx/H:1_4/I:xx-xx@xx+xx&xx-xx|xx+xx/J:1_4/K:4+4-12", + "N^pau-i+ch=i/A:-1+1+4/B:05-xx_xx/C:05_xx+xx/D:05+xx_xx/E:4_3!0_xx-0/F:4_2#1_xx@1_1|1_4/G:xx_xx%xx_xx_xx/H:1_4/I:1-4@4+1&4-1|9+4/J:xx_xx/K:4+4-12", + "pau^i-ch+i=o/A:0+2+3/B:05-xx_xx/C:05_xx+xx/D:05+xx_xx/E:4_3!0_xx-0/F:4_2#1_xx@1_1|1_4/G:xx_xx%xx_xx_xx/H:1_4/I:1-4@4+1&4-1|9+4/J:xx_xx/K:4+4-12", + "i^ch-i+o=k/A:0+2+3/B:05-xx_xx/C:05_xx+xx/D:05+xx_xx/E:4_3!0_xx-0/F:4_2#1_xx@1_1|1_4/G:xx_xx%xx_xx_xx/H:1_4/I:1-4@4+1&4-1|9+4/J:xx_xx/K:4+4-12", + "ch^i-o+k=u/A:1+3+2/B:05-xx_xx/C:05_xx+xx/D:xx+xx_xx/E:4_3!0_xx-0/F:4_2#1_xx@1_1|1_4/G:xx_xx%xx_xx_xx/H:1_4/I:1-4@4+1&4-1|9+4/J:xx_xx/K:4+4-12", + "i^o-k+u=sil/A:2+4+1/B:05-xx_xx/C:05_xx+xx/D:xx+xx_xx/E:4_3!0_xx-0/F:4_2#1_xx@1_1|1_4/G:xx_xx%xx_xx_xx/H:1_4/I:1-4@4+1&4-1|9+4/J:xx_xx/K:4+4-12", + "o^k-u+sil=xx/A:2+4+1/B:05-xx_xx/C:05_xx+xx/D:xx+xx_xx/E:4_3!0_xx-0/F:4_2#1_xx@1_1|1_4/G:xx_xx%xx_xx_xx/H:1_4/I:1-4@4+1&4-1|9+4/J:xx_xx/K:4+4-12", + "k^u-sil+xx=xx/A:xx+xx+xx/B:05-xx_xx/C:xx_xx+xx/D:xx+xx_xx/E:4_2!1_xx-xx/F:xx_xx#xx_xx@xx_xx|xx_xx/G:xx_xx%xx_xx_xx/H:1_4/I:xx-xx@xx+xx&xx-xx|xx+xx/J:xx_xx/K:4+4-12", + ], + &[ + AccentPhraseModel::new( + vec![ + mora("イ", None, "i"), + mora("チ", Some("ch"), "i"), + ], + 2, + Some(mora("、", None, "pau")), + false, + ), + AccentPhraseModel::new( + vec![ + mora("セ", Some("s"), "e"), + mora("ン", None, "N"), + ], + 1, + Some(mora("、", None, "pau")), + false, + ), + AccentPhraseModel::new( + vec![ + mora("ヒャ", Some("hy"), "a"), + mora("ク", Some("k"), "u"), + mora("マ", Some("m"), "a"), + mora("ン", None, "N"), + ], + 3, + Some(mora("、", None, "pau")), + false, + ), + AccentPhraseModel::new( + vec![ + mora("イ", None, "i"), + mora("チ", Some("ch"), "i"), + mora("オ", None, "o"), + mora("ク", Some("k"), "u"), + ], + 2, + None, + true, + ), + ] + )] + #[case( + "クヮルテット。あーあ、。", + &[ + "xx^xx-sil+kw=a/A:xx+xx+xx/B:xx-xx_xx/C:xx_xx+xx/D:02+xx_xx/E:xx_xx!xx_xx-xx/F:xx_xx#xx_xx@xx_xx|xx_xx/G:5_3%0_xx_xx/H:xx_xx/I:xx-xx@xx+xx&xx-xx|xx+xx/J:1_5/K:2+3-8", + "xx^sil-kw+a=r/A:-2+1+5/B:xx-xx_xx/C:02_xx+xx/D:09+xx_xx/E:xx_xx!xx_xx-xx/F:5_3#0_xx@1_1|1_5/G:2_1%0_xx_0/H:xx_xx/I:1-5@1+2&1-3|1+8/J:2_3/K:2+3-8", + "sil^kw-a+r=u/A:-2+1+5/B:xx-xx_xx/C:02_xx+xx/D:09+xx_xx/E:xx_xx!xx_xx-xx/F:5_3#0_xx@1_1|1_5/G:2_1%0_xx_0/H:xx_xx/I:1-5@1+2&1-3|1+8/J:2_3/K:2+3-8", + "kw^a-r+u=t/A:-1+2+4/B:xx-xx_xx/C:02_xx+xx/D:09+xx_xx/E:xx_xx!xx_xx-xx/F:5_3#0_xx@1_1|1_5/G:2_1%0_xx_0/H:xx_xx/I:1-5@1+2&1-3|1+8/J:2_3/K:2+3-8", + "a^r-u+t=e/A:-1+2+4/B:xx-xx_xx/C:02_xx+xx/D:09+xx_xx/E:xx_xx!xx_xx-xx/F:5_3#0_xx@1_1|1_5/G:2_1%0_xx_0/H:xx_xx/I:1-5@1+2&1-3|1+8/J:2_3/K:2+3-8", + "r^u-t+e=cl/A:0+3+3/B:xx-xx_xx/C:02_xx+xx/D:09+xx_xx/E:xx_xx!xx_xx-xx/F:5_3#0_xx@1_1|1_5/G:2_1%0_xx_0/H:xx_xx/I:1-5@1+2&1-3|1+8/J:2_3/K:2+3-8", + "u^t-e+cl=t/A:0+3+3/B:xx-xx_xx/C:02_xx+xx/D:09+xx_xx/E:xx_xx!xx_xx-xx/F:5_3#0_xx@1_1|1_5/G:2_1%0_xx_0/H:xx_xx/I:1-5@1+2&1-3|1+8/J:2_3/K:2+3-8", + "t^e-cl+t=o/A:1+4+2/B:xx-xx_xx/C:02_xx+xx/D:09+xx_xx/E:xx_xx!xx_xx-xx/F:5_3#0_xx@1_1|1_5/G:2_1%0_xx_0/H:xx_xx/I:1-5@1+2&1-3|1+8/J:2_3/K:2+3-8", + "e^cl-t+o=pau/A:2+5+1/B:xx-xx_xx/C:02_xx+xx/D:09+xx_xx/E:xx_xx!xx_xx-xx/F:5_3#0_xx@1_1|1_5/G:2_1%0_xx_0/H:xx_xx/I:1-5@1+2&1-3|1+8/J:2_3/K:2+3-8", + "cl^t-o+pau=a/A:2+5+1/B:xx-xx_xx/C:02_xx+xx/D:09+xx_xx/E:xx_xx!xx_xx-xx/F:5_3#0_xx@1_1|1_5/G:2_1%0_xx_0/H:xx_xx/I:1-5@1+2&1-3|1+8/J:2_3/K:2+3-8", + "t^o-pau+a=a/A:xx+xx+xx/B:02-xx_xx/C:xx_xx+xx/D:09+xx_xx/E:5_3!0_xx-xx/F:xx_xx#xx_xx@xx_xx|xx_xx/G:2_1%0_xx_xx/H:1_5/I:xx-xx@xx+xx&xx-xx|xx+xx/J:2_3/K:2+3-8", + "o^pau-a+a=a/A:0+1+2/B:02-xx_xx/C:09_xx+xx/D:09+xx_xx/E:5_3!0_xx-0/F:2_1#0_xx@1_2|1_3/G:1_1%0_xx_1/H:1_5/I:2-3@2+1&2-2|6+3/J:xx_xx/K:2+3-8", + "pau^a-a+a=sil/A:1+2+1/B:02-xx_xx/C:09_xx+xx/D:09+xx_xx/E:5_3!0_xx-0/F:2_1#0_xx@1_2|1_3/G:1_1%0_xx_1/H:1_5/I:2-3@2+1&2-2|6+3/J:xx_xx/K:2+3-8", + "a^a-a+sil=xx/A:0+1+1/B:09-xx_xx/C:09_xx+xx/D:xx+xx_xx/E:2_1!0_xx-1/F:1_1#0_xx@2_1|3_1/G:xx_xx%xx_xx_xx/H:1_5/I:2-3@2+1&2-2|6+3/J:xx_xx/K:2+3-8", + "a^a-sil+xx=xx/A:xx+xx+xx/B:09-xx_xx/C:xx_xx+xx/D:xx+xx_xx/E:1_1!0_xx-xx/F:xx_xx#xx_xx@xx_xx|xx_xx/G:xx_xx%xx_xx_xx/H:2_3/I:xx-xx@xx+xx&xx-xx|xx+xx/J:xx_xx/K:2+3-8", + ], + &[ + AccentPhraseModel::new( + vec![ + mora("クヮ", Some("kw"), "a"), + mora("ル", Some("r"), "u"), + mora("テ", Some("t"), "e"), + mora("ッ", None, "cl"), + mora("ト", Some("t"), "o"), + ], + 3, + Some(mora("、", None, "pau")), + false, + ), + AccentPhraseModel::new( + vec![ + mora("ア", None, "a"), + mora("ア", None, "a"), + ], + 1, + None, + false, + ), + AccentPhraseModel::new( + vec![mora("ア", None, "a")], + 1, + None, + false, + ), + ] + )] + fn label_cases( + #[case] text: &str, + #[case] labels: &[&str], + #[case] accent_phrase: &[AccentPhraseModel], + ) { + } + + #[apply(label_cases)] + #[tokio::test] + async fn open_jtalk(text: &str, labels: &[&str], _accent_phrase: &[AccentPhraseModel]) { + let open_jtalk = crate::tokio::OpenJtalk::new(OPEN_JTALK_DIC_DIR) + .await + .unwrap(); + assert_eq!(&open_jtalk.extract_fullcontext(text).unwrap(), labels); + } + + #[apply(label_cases)] + #[tokio::test] + async fn extract_fullcontext( + text: &str, + _labels: &[&str], + accent_phrase: &[AccentPhraseModel], + ) { + let open_jtalk = crate::tokio::OpenJtalk::new(OPEN_JTALK_DIC_DIR) + .await + .unwrap(); + let analyzer = OpenJTalkAnalyzer::new(open_jtalk); + assert_eq!(analyzer.analyze(text).unwrap(), accent_phrase); + } +} diff --git a/crates/voicevox_core/src/engine/model.rs b/crates/voicevox_core/src/engine/model.rs index 77adbebe7..de0f388f9 100644 --- a/crates/voicevox_core/src/engine/model.rs +++ b/crates/voicevox_core/src/engine/model.rs @@ -5,7 +5,7 @@ use serde::{Deserialize, Serialize}; /* 各フィールドのjsonフィールド名はsnake_caseとする*/ /// モーラ(子音+母音)ごとの情報。 -#[derive(Clone, Debug, new, Getters, Deserialize, Serialize)] +#[derive(Clone, Debug, new, Getters, Deserialize, Serialize, PartialEq)] pub struct MoraModel { /// 文字。 text: String, @@ -22,7 +22,7 @@ pub struct MoraModel { } /// AccentPhrase (アクセント句ごとの情報)。 -#[derive(Clone, Debug, new, Getters, Deserialize, Serialize)] +#[derive(Clone, Debug, new, Getters, Deserialize, Serialize, PartialEq)] pub struct AccentPhraseModel { /// モーラの配列。 moras: Vec, diff --git a/crates/voicevox_core/src/lib.rs b/crates/voicevox_core/src/lib.rs index f0a948354..c4b9834c3 100644 --- a/crates/voicevox_core/src/lib.rs +++ b/crates/voicevox_core/src/lib.rs @@ -24,6 +24,11 @@ pub mod tokio; #[cfg(test)] mod test_util; +// https://crates.io/crates/rstest_reuse#use-rstest_resuse-at-the-top-of-your-crate +#[allow(clippy::single_component_path_imports)] +#[cfg(test)] +use rstest_reuse; + pub use self::{ devices::SupportedDevices, engine::{AccentPhraseModel, AudioQueryModel, FullcontextExtractor},