diff options
| author | 魏曹先生 <1992414357@qq.com> | 2026-06-28 09:06:08 +0800 |
|---|---|---|
| committer | 魏曹先生 <1992414357@qq.com> | 2026-06-28 09:06:08 +0800 |
| commit | 748c14588cf1c31c8b8d60a9c94349c0173ef607 (patch) | |
| tree | 4c09bfafd93b629a68f0f78902a33e8dd9ef18d1 /mingling_pathf/test/src | |
| parent | 50f2d767e2d07685e49fb7deae68d506ea11a79d (diff) | |
feat(pathf): add build-time type path resolution system
Add `mingling_pathf` sub-crate and `pathf` feature for automatic
resolution of Mingling type module paths at build time. Scans source
files, identifies macro invocations via pattern matchers, and generates
mapping files consumed by `gen_program!()`.
Diffstat (limited to 'mingling_pathf/test/src')
| -rw-r--r-- | mingling_pathf/test/src/.gitignore | 1 | ||||
| -rw-r--r-- | mingling_pathf/test/src/lib.rs | 235 | ||||
| -rw-r--r-- | mingling_pathf/test/src/test_files/test_chain.rs | 61 | ||||
| -rw-r--r-- | mingling_pathf/test/src/test_files/test_completion.rs | 41 | ||||
| -rw-r--r-- | mingling_pathf/test/src/test_files/test_dispatcher.rs | 17 | ||||
| -rw-r--r-- | mingling_pathf/test/src/test_files/test_dispatcher_clap.rs | 33 | ||||
| -rw-r--r-- | mingling_pathf/test/src/test_files/test_group.rs | 13 | ||||
| -rw-r--r-- | mingling_pathf/test/src/test_files/test_groupped_derive.rs | 26 | ||||
| -rw-r--r-- | mingling_pathf/test/src/test_files/test_help.rs | 33 | ||||
| -rw-r--r-- | mingling_pathf/test/src/test_files/test_pack.rs | 17 | ||||
| -rw-r--r-- | mingling_pathf/test/src/test_files/test_renderer.rs | 33 |
11 files changed, 510 insertions, 0 deletions
diff --git a/mingling_pathf/test/src/.gitignore b/mingling_pathf/test/src/.gitignore new file mode 100644 index 0000000..13bd6e1 --- /dev/null +++ b/mingling_pathf/test/src/.gitignore @@ -0,0 +1 @@ +main.rs diff --git a/mingling_pathf/test/src/lib.rs b/mingling_pathf/test/src/lib.rs index f2ca3e0..2fcf01a 100644 --- a/mingling_pathf/test/src/lib.rs +++ b/mingling_pathf/test/src/lib.rs @@ -1,6 +1,7 @@ #![cfg(test)] use std::{collections::HashMap, env::current_dir}; +use mingling_pathf::analyze_and_build_type_mapping_for; #[test] fn test_module_pathf() { @@ -46,3 +47,237 @@ fn test_pattern_analyzer_once() { let result = analyzer.analyze_file(dir.join("src/has_sub_mod.rs")).unwrap(); assert!(result.contains("::directly_sub_mod::DirectlySubModStruct")); } + +#[test] +fn test_chain_analyze() { + let analyzer = mingling_pathf::pattern_analyzer::init(); + let file = current_dir().unwrap().join("src/test_files/test_chain.rs"); + + let r = analyzer.analyze_file(file).unwrap(); + let required_entries: Vec<&str> = vec![ + "::sub::__internal_chain_my_chain1", + "::sub::__internal_chain_my_chain2", + "::sub::__internal_chain_my_chain3", + "::sub::__internal_chain_my_chain4", + "::sub::__internal_chain_my_chain5", + "::sub::__internal_chain_my_chain6", + "::__internal_chain_my_chain1", + "::__internal_chain_my_chain2", + "::__internal_chain_my_chain3", + "::__internal_chain_my_chain4", + "::__internal_chain_my_chain5", + "::__internal_chain_my_chain6", + ]; + + assert_eq!(r.len(), required_entries.len(), "Result should contain exactly {} entries", required_entries.len()); + + for entry in &required_entries { + assert!(r.iter().any(|e| e == entry), "Result should contain: {}", entry); + } +} + +#[test] +fn test_renderer_analyze() { + let analyzer = mingling_pathf::pattern_analyzer::init(); + let file = current_dir().unwrap().join("src/test_files/test_renderer.rs"); + + let r = analyzer.analyze_file(file).unwrap(); + let required: Vec<&str> = vec![ + "::sub::__internal_renderer_my_renderer1", + "::sub::__internal_renderer_my_renderer2", + "::sub::__internal_renderer_my_renderer3", + "::sub::__internal_renderer_my_renderer4", + "::__internal_renderer_my_renderer1", + "::__internal_renderer_my_renderer2", + "::__internal_renderer_my_renderer3", + "::__internal_renderer_my_renderer4", + ]; + + assert_eq!(r.len(), required.len()); + for entry in &required { + assert!(r.contains(*entry), "Result should contain: {}", entry); + } +} + +#[test] +fn test_help_analyze() { + let analyzer = mingling_pathf::pattern_analyzer::init(); + let file = current_dir().unwrap().join("src/test_files/test_help.rs"); + + let r = analyzer.analyze_file(file).unwrap(); + let required: Vec<&str> = vec![ + "::sub::__internal_help_my_help1", + "::sub::__internal_help_my_help2", + "::sub::__internal_help_my_help3", + "::sub::__internal_help_my_help4", + "::__internal_help_my_help1", + "::__internal_help_my_help2", + "::__internal_help_my_help3", + "::__internal_help_my_help4", + ]; + + assert_eq!(r.len(), required.len()); + for entry in &required { + assert!(r.contains(*entry), "Result should contain: {}", entry); + } +} + +#[test] +fn test_completion_analyze() { + let analyzer = mingling_pathf::pattern_analyzer::init(); + let file = current_dir().unwrap().join("src/test_files/test_completion.rs"); + + let r = analyzer.analyze_file(file).unwrap(); + let required: Vec<&str> = vec![ + "::sub::__internal_completion_my_completion1", + "::sub::__internal_completion_my_completion2", + "::sub::__internal_completion_my_completion3", + "::sub::__internal_completion_my_completion4", + "::__internal_completion_my_completion1", + "::__internal_completion_my_completion2", + "::__internal_completion_my_completion3", + "::__internal_completion_my_completion4", + ]; + + assert_eq!(r.len(), required.len()); + for entry in &required { + assert!(r.contains(*entry), "Result should contain: {}", entry); + } +} + +#[test] +fn test_pack_analyze() { + let analyzer = mingling_pathf::pattern_analyzer::init(); + let file = current_dir().unwrap().join("src/test_files/test_pack.rs"); + + let r = analyzer.analyze_file(file).unwrap(); + let required: Vec<&str> = vec![ + "::ResultPack1", + "::ErrorPack1", + "::ErrorPack2", + "::ResultPack2", + "::ErrorPack3", + "::ErrorPack4", + "::sub::ResultPack1", + "::sub::ErrorPack1", + "::sub::ErrorPack2", + "::sub::ResultPack2", + "::sub::ErrorPack3", + "::sub::ErrorPack4", + ]; + + assert_eq!(r.len(), required.len()); + for entry in &required { + assert!(r.contains(*entry), "Result should contain: {}", entry); + } +} + +#[test] +fn test_group_analyze() { + let analyzer = mingling_pathf::pattern_analyzer::init(); + let file = current_dir().unwrap().join("src/test_files/test_group.rs"); + + let r = analyzer.analyze_file(file).unwrap(); + let required: Vec<&str> = vec![ + "::Group1", + "::GroupAlias1", + "::Group2", + "::GroupAlias2", + "::sub::Group1", + "::sub::GroupAlias1", + "::sub::Group2", + "::sub::GroupAlias2", + ]; + + assert_eq!(r.len(), required.len()); + for entry in &required { + assert!(r.contains(*entry), "Result should contain: {}", entry); + } +} + +#[test] +fn test_groupped_derive_analyze() { + let analyzer = mingling_pathf::pattern_analyzer::init(); + let file = current_dir().unwrap().join("src/test_files/test_groupped_derive.rs"); + + let r = analyzer.analyze_file(file).unwrap(); + let required: Vec<&str> = vec![ + "::Derived1", + "::Derived2", + "::Derived3", + "::sub::Derived1", + "::sub::Derived3", + ]; + + assert_eq!(r.len(), required.len()); + for entry in &required { + assert!(r.contains(*entry), "Result should contain: {}", entry); + } +} + +#[test] +fn test_dispatcher_analyze() { + let analyzer = mingling_pathf::pattern_analyzer::init(); + let file = current_dir().unwrap().join("src/test_files/test_dispatcher.rs"); + + let r = analyzer.analyze_file(file).unwrap(); + let required: Vec<&str> = vec![ + "::EntryGreet", + "::EntryRemoteAdd", + "::EntryAdd", + "::EntryDelete", + "::EntryRemoteRm", + "::EntryRm", + "::sub::EntryGreet", + "::sub::EntryDelete", + ]; + + assert_eq!(r.len(), required.len()); + for entry in &required { + assert!(r.contains(*entry), "Result should contain: {}", entry); + } +} + +#[test] +fn test_dispatcher_clap_analyze() { + let analyzer = mingling_pathf::pattern_analyzer::init(); + let file = current_dir().unwrap().join("src/test_files/test_dispatcher_clap.rs"); + + let r = analyzer.analyze_file(file).unwrap(); + let required: Vec<&str> = vec![ + "::EntryClap1", + "::EntryClap2", + "::EntryClap3", + "::EntryClap4", + "::sub::EntryClap1", + "::sub::EntryClap3", + ]; + + assert_eq!(r.len(), required.len()); + for entry in &required { + assert!(r.contains(*entry), "Result should contain: {}", entry); + } +} + +#[test] +fn test_type_mapping_file_created() { + let tmp = std::env::temp_dir().join("mingling_pathf_test_type_mapping"); + let _ = std::fs::remove_dir_all(&tmp); + + let crate_dir = std::path::Path::new(env!("CARGO_MANIFEST_DIR")); + + analyze_and_build_type_mapping_for( + crate_dir, + &tmp, + ) + .unwrap(); + + let output_path = tmp.join("type-mapping"); + assert!( + output_path.exists(), + "type-mapping file should exist at: {}", + output_path.display() + ); + + let _ = std::fs::remove_dir_all(&tmp); +} diff --git a/mingling_pathf/test/src/test_files/test_chain.rs b/mingling_pathf/test/src/test_files/test_chain.rs new file mode 100644 index 0000000..e209a5e --- /dev/null +++ b/mingling_pathf/test/src/test_files/test_chain.rs @@ -0,0 +1,61 @@ +#[mingling::macros::chain] +fn my_chain1(prev: Some1) -> Next { + +} + +#[mingling::macros::chain] +pub fn my_chain2(prev: Some2) -> Next { + +} + +#[mingling::macros::chain] +pub async fn my_chain3(prev: Some3) -> Next { + +} + +#[chain] +fn my_chain4(prev: Some4) { + +} + +#[chain] +pub fn my_chain5(prev: Some5) { + +} + +#[chain] +pub async fn my_chain6(prev: Some6) { + +} + +pub mod sub { + #[mingling::macros::chain] + fn my_chain1(prev: Some1) -> Next { + + } + + #[mingling::macros::chain] + pub fn my_chain2(prev: Some2) -> Next { + + } + + #[mingling::macros::chain] + pub async fn my_chain3(prev: Some3) -> Next { + + } + + #[chain] + fn my_chain4(prev: Some4) { + + } + + #[chain] + pub fn my_chain5(prev: Some5) { + + } + + #[chain] + pub async fn my_chain6(prev: Some6) { + + } +} diff --git a/mingling_pathf/test/src/test_files/test_completion.rs b/mingling_pathf/test/src/test_files/test_completion.rs new file mode 100644 index 0000000..87a655f --- /dev/null +++ b/mingling_pathf/test/src/test_files/test_completion.rs @@ -0,0 +1,41 @@ +#[mingling::macros::completion(Some1)] +fn my_completion1(ctx: &mingling::ShellContext) -> mingling::Suggest { + mingling::Suggest::new() +} + +#[mingling::macros::completion(Some2)] +pub fn my_completion2(ctx: &mingling::ShellContext) -> mingling::Suggest { + mingling::Suggest::new() +} + +#[completion(Some3)] +fn my_completion3(ctx: &mingling::ShellContext) -> mingling::Suggest { + mingling::Suggest::new() +} + +#[completion(Some4)] +pub fn my_completion4(ctx: &mingling::ShellContext) -> mingling::Suggest { + mingling::Suggest::new() +} + +pub mod sub { + #[mingling::macros::completion(Some1)] + fn my_completion1(ctx: &mingling::ShellContext) -> mingling::Suggest { + mingling::Suggest::new() + } + + #[mingling::macros::completion(Some2)] + pub fn my_completion2(ctx: &mingling::ShellContext) -> mingling::Suggest { + mingling::Suggest::new() + } + + #[completion(Some3)] + fn my_completion3(ctx: &mingling::ShellContext) -> mingling::Suggest { + mingling::Suggest::new() + } + + #[completion(Some4)] + pub fn my_completion4(ctx: &mingling::ShellContext) -> mingling::Suggest { + mingling::Suggest::new() + } +} diff --git a/mingling_pathf/test/src/test_files/test_dispatcher.rs b/mingling_pathf/test/src/test_files/test_dispatcher.rs new file mode 100644 index 0000000..48f5e4d --- /dev/null +++ b/mingling_pathf/test/src/test_files/test_dispatcher.rs @@ -0,0 +1,17 @@ +mingling::macros::dispatcher!("greet", CMDGreet => EntryGreet); +mingling::macros::dispatcher!("greet"); +mingling::macros::dispatcher!("remote.add", CMDRemoteAdd => EntryRemoteAdd); +mingling::macros::dispatcher!("remote.add"); + +dispatcher!("delete", CMDDelete => EntryDelete); +dispatcher!("delete"); +dispatcher!("remote.rm", CMDRemoteRm => EntryRemoteRm); +dispatcher!("remote.rm"); + +pub mod sub { + mingling::macros::dispatcher!("greet", CMDGreet => EntryGreet); + mingling::macros::dispatcher!("greet"); + + dispatcher!("delete", CMDDelete => EntryDelete); + dispatcher!("delete"); +} diff --git a/mingling_pathf/test/src/test_files/test_dispatcher_clap.rs b/mingling_pathf/test/src/test_files/test_dispatcher_clap.rs new file mode 100644 index 0000000..0ba884d --- /dev/null +++ b/mingling_pathf/test/src/test_files/test_dispatcher_clap.rs @@ -0,0 +1,33 @@ +#[mingling::macros::dispatcher_clap] +struct EntryClap1 { + name: String, + age: i32, +} + +#[mingling::macros::dispatcher_clap] +#[command(name = "greet")] +pub struct EntryClap2 { + name: String, +} + +#[dispatcher_clap] +struct EntryClap3 { + value: String, +} + +#[dispatcher_clap] +pub struct EntryClap4 { + value: i32, +} + +pub mod sub { + #[mingling::macros::dispatcher_clap] + struct EntryClap1 { + name: String, + } + + #[dispatcher_clap] + struct EntryClap3 { + value: String, + } +} diff --git a/mingling_pathf/test/src/test_files/test_group.rs b/mingling_pathf/test/src/test_files/test_group.rs new file mode 100644 index 0000000..92c8cda --- /dev/null +++ b/mingling_pathf/test/src/test_files/test_group.rs @@ -0,0 +1,13 @@ +mingling::macros::group!(Group1); +mingling::macros::group!(GroupAlias1 = std::io::Error); + +group!(Group2); +group!(GroupAlias2 = std::num::ParseIntError); + +pub mod sub { + mingling::macros::group!(Group1); + mingling::macros::group!(GroupAlias1 = std::io::Error); + + group!(Group2); + group!(GroupAlias2 = std::num::ParseIntError); +} diff --git a/mingling_pathf/test/src/test_files/test_groupped_derive.rs b/mingling_pathf/test/src/test_files/test_groupped_derive.rs new file mode 100644 index 0000000..f6c6fa9 --- /dev/null +++ b/mingling_pathf/test/src/test_files/test_groupped_derive.rs @@ -0,0 +1,26 @@ +#[derive(Groupped)] +struct Derived1 { + value: String, +} + +#[derive(Groupped, Debug, Clone)] +struct Derived2 { + value: i32, +} + +#[derive(GrouppedSerialize)] +struct Derived3 { + value: bool, +} + +pub mod sub { + #[derive(Groupped)] + struct Derived1 { + value: String, + } + + #[derive(GrouppedSerialize)] + struct Derived3 { + value: bool, + } +} diff --git a/mingling_pathf/test/src/test_files/test_help.rs b/mingling_pathf/test/src/test_files/test_help.rs new file mode 100644 index 0000000..52d1408 --- /dev/null +++ b/mingling_pathf/test/src/test_files/test_help.rs @@ -0,0 +1,33 @@ +#[mingling::macros::help] +fn my_help1(prev: Some1) { +} + +#[mingling::macros::help] +pub fn my_help2(prev: Some2) { +} + +#[help] +fn my_help3(prev: Some3) { +} + +#[help] +pub fn my_help4(prev: Some4) { +} + +pub mod sub { + #[mingling::macros::help] + fn my_help1(prev: Some1) { + } + + #[mingling::macros::help] + pub fn my_help2(prev: Some2) { + } + + #[help] + fn my_help3(prev: Some3) { + } + + #[help] + pub fn my_help4(prev: Some4) { + } +} diff --git a/mingling_pathf/test/src/test_files/test_pack.rs b/mingling_pathf/test/src/test_files/test_pack.rs new file mode 100644 index 0000000..759e35f --- /dev/null +++ b/mingling_pathf/test/src/test_files/test_pack.rs @@ -0,0 +1,17 @@ +mingling::macros::pack!(ResultPack1 = String); +mingling::macros::pack_err!(ErrorPack1); +mingling::macros::pack_err!(ErrorPack2 = PathBuf); + +pack!(ResultPack2 = (u8, String)); +pack_err!(ErrorPack3); +pack_err!(ErrorPack4 = PathBuf); + +pub mod sub { + mingling::macros::pack!(ResultPack1 = String); + mingling::macros::pack_err!(ErrorPack1); + mingling::macros::pack_err!(ErrorPack2 = PathBuf); + + pack!(ResultPack2 = (u8, String)); + pack_err!(ErrorPack3); + pack_err!(ErrorPack4 = PathBuf); +} diff --git a/mingling_pathf/test/src/test_files/test_renderer.rs b/mingling_pathf/test/src/test_files/test_renderer.rs new file mode 100644 index 0000000..ea52f5c --- /dev/null +++ b/mingling_pathf/test/src/test_files/test_renderer.rs @@ -0,0 +1,33 @@ +#[mingling::macros::renderer] +fn my_renderer1(prev: Some1) { +} + +#[mingling::macros::renderer] +pub fn my_renderer2(prev: Some2) { +} + +#[renderer] +fn my_renderer3(prev: Some3) { +} + +#[renderer] +pub fn my_renderer4(prev: Some4) { +} + +pub mod sub { + #[mingling::macros::renderer] + fn my_renderer1(prev: Some1) { + } + + #[mingling::macros::renderer] + pub fn my_renderer2(prev: Some2) { + } + + #[renderer] + fn my_renderer3(prev: Some3) { + } + + #[renderer] + pub fn my_renderer4(prev: Some4) { + } +} |
