1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
// / CLI for Mostro
// / Initialize the default directory for the settings file
//! CLI
use crate::config::util::init_configuration_file;
use clap::Parser;
#[derive(Parser)]
#[command(
name = "mostro p2p",
about = "A P2P lightning exchange over Nostr",
author,
help_template = "\
{before-help}{name}
{about-with-newline}
{author-with-newline}
{usage-heading} {usage}
{all-args}{after-help}
",
version
)]
#[command(propagate_version = true)]
#[command(arg_required_else_help(false))]
pub struct Cli {
/// Set folder for Mostro settings file - default is HOME/.mostro
#[arg(short, long)]
dirsettings: Option<String>,
}
/// Initialize the settings file and create the global config variable for Mostro settings
/// Default folder is HOME but user can specify a custom folder with dirsettings (-d ) parameter from CLI
/// Example: mostro p2p -d /user_folder/mostro
///
pub fn settings_init() -> Result<(), Box<dyn std::error::Error>> {
// Parse CLI arguments
let cli = Cli::parse();
// Select config file from CLI or default to HOME/.mostro
// create config file if it doesn't exist
if let Some(path) = cli.dirsettings.as_deref() {
init_configuration_file(Some(path.to_string()))?
} else {
init_configuration_file(None)?
};
// Mostro settings are initialized
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
use clap::Parser;
#[test]
fn test_cli_parser_creation() {
// Test that CLI struct can be created
let cli = Cli { dirsettings: None };
assert!(cli.dirsettings.is_none());
let cli_with_path = Cli {
dirsettings: Some("/custom/path".to_string()),
};
assert_eq!(cli_with_path.dirsettings.unwrap(), "/custom/path");
}
#[test]
fn test_cli_parsing_help() {
// Test that help can be parsed without panicking
let result = Cli::try_parse_from(["mostro", "--help"]);
assert!(result.is_err()); // Help exits with error code
}
#[test]
fn test_cli_parsing_version() {
// Test that version can be parsed without panicking
let result = Cli::try_parse_from(["mostro", "--version"]);
assert!(result.is_err()); // Version exits with error code
}
#[test]
fn test_cli_parsing_no_args() {
// Test parsing with no arguments (should succeed)
let result = Cli::try_parse_from(["mostro"]);
assert!(result.is_ok());
let cli = result.unwrap();
assert!(cli.dirsettings.is_none());
}
#[test]
fn test_cli_parsing_with_dirsettings_short() {
// Test parsing with short flag -d
let result = Cli::try_parse_from(["mostro", "-d", "/test/path"]);
assert!(result.is_ok());
let cli = result.unwrap();
assert_eq!(cli.dirsettings.unwrap(), "/test/path");
}
#[test]
fn test_cli_parsing_with_dirsettings_long() {
// Test parsing with long flag --dirsettings
let result = Cli::try_parse_from(["mostro", "--dirsettings", "/test/path"]);
assert!(result.is_ok());
let cli = result.unwrap();
assert_eq!(cli.dirsettings.unwrap(), "/test/path");
}
#[test]
fn test_cli_parsing_invalid_args() {
// Test parsing with invalid arguments
let result = Cli::try_parse_from(["mostro", "--invalid"]);
assert!(result.is_err());
}
mod settings_init_tests {
use super::*;
#[test]
fn test_settings_init_structure() {
// This is a structural test since we can't easily mock the CLI parsing
// In a real implementation, we would need dependency injection for testing
// Test that the function signature is correct
let _: fn() -> Result<(), Box<dyn std::error::Error>> = settings_init;
// Verify function exists and has correct return type
// No-op: type check above is sufficient
}
#[test]
fn test_custom_path_handling() {
// Test the logical flow of custom path handling
let custom_path = Some("/custom/path".to_string());
let cli = Cli {
dirsettings: custom_path.clone(),
};
if let Some(path) = cli.dirsettings.as_deref() {
assert_eq!(path, "/custom/path");
} else {
panic!("Custom path should be present");
}
}
#[test]
fn test_default_path_handling() {
// Test the logical flow of default path handling
let cli = Cli { dirsettings: None };
if cli.dirsettings.is_none() {
// This is the expected path for default settings
// No-op: branch reached is the assertion
} else {
panic!("Default path should be None");
}
}
}
}