Skip to content

Commit 28816b4

Browse files
committed
feat: update test case
1 parent dc5a294 commit 28816b4

File tree

3 files changed

+184
-76
lines changed

3 files changed

+184
-76
lines changed

src/linux.rs

Lines changed: 79 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -43,20 +43,7 @@ impl AutoLaunch {
4343

4444
/// Enable using XDG Autostart (.desktop file)
4545
fn enable_xdg_autostart(&self) -> Result<()> {
46-
let data = format!(
47-
"[Desktop Entry]\n\
48-
Type=Application\n\
49-
Version=1.0\n\
50-
Name={}\n\
51-
Comment={} startup script\n\
52-
Exec={} {}\n\
53-
StartupNotify=false\n\
54-
Terminal=false",
55-
self.app_name,
56-
self.app_name,
57-
self.app_path,
58-
self.args.join(" ")
59-
);
46+
let data = build_xdg_autostart_data(&self.app_name, &self.app_path, &self.args);
6047

6148
let dir = get_xdg_autostart_dir()?;
6249
if !dir.exists() {
@@ -81,27 +68,7 @@ impl AutoLaunch {
8168
/// Enable using systemd user service
8269
fn enable_systemd(&self) -> Result<()> {
8370
// Create systemd service file content
84-
let args_str = if self.args.is_empty() {
85-
String::new()
86-
} else {
87-
format!(" {}", self.args.join(" "))
88-
};
89-
90-
let data = format!(
91-
"[Unit]\n\
92-
Description={}\n\
93-
After=default.target\n\
94-
\n\
95-
[Service]\n\
96-
Type=simple\n\
97-
ExecStart={}{}\n\
98-
Restart=on-failure\n\
99-
RestartSec=10\n\
100-
\n\
101-
[Install]\n\
102-
WantedBy=default.target",
103-
self.app_name, self.app_path, args_str
104-
);
71+
let data = build_systemd_service_data(&self.app_name, &self.app_path, &self.args);
10572

10673
// Create systemd user directory
10774
let dir = get_systemd_user_dir()?;
@@ -247,6 +214,47 @@ impl AutoLaunch {
247214
}
248215
}
249216

217+
fn build_xdg_autostart_data(app_name: &str, app_path: &str, args: &[String]) -> String {
218+
format!(
219+
"[Desktop Entry]\n\
220+
Type=Application\n\
221+
Version=1.0\n\
222+
Name={}\n\
223+
Comment={} startup script\n\
224+
Exec={} {}\n\
225+
StartupNotify=false\n\
226+
Terminal=false",
227+
app_name,
228+
app_name,
229+
app_path,
230+
args.join(" ")
231+
)
232+
}
233+
234+
fn build_systemd_service_data(app_name: &str, app_path: &str, args: &[String]) -> String {
235+
let args_str = if args.is_empty() {
236+
String::new()
237+
} else {
238+
format!(" {}", args.join(" "))
239+
};
240+
241+
format!(
242+
"[Unit]\n\
243+
Description={}\n\
244+
After=default.target\n\
245+
\n\
246+
[Service]\n\
247+
Type=simple\n\
248+
ExecStart={}{}\n\
249+
Restart=on-failure\n\
250+
RestartSec=10\n\
251+
\n\
252+
[Install]\n\
253+
WantedBy=default.target",
254+
app_name, app_path, args_str
255+
)
256+
}
257+
250258
/// Get the XDG autostart directory
251259
fn get_xdg_autostart_dir() -> Result<PathBuf> {
252260
let home_dir = dirs::home_dir().ok_or_else(|| {
@@ -262,3 +270,39 @@ fn get_systemd_user_dir() -> Result<PathBuf> {
262270
})?;
263271
Ok(home_dir.join(".config").join("systemd").join("user"))
264272
}
273+
274+
#[cfg(test)]
275+
mod tests {
276+
use super::*;
277+
278+
#[test]
279+
fn test_build_xdg_autostart_data() {
280+
let data = build_xdg_autostart_data(
281+
"TestApp",
282+
"/opt/test-app",
283+
&vec!["--flag".into(), "value".into()],
284+
);
285+
286+
assert!(data.contains("Type=Application"));
287+
assert!(data.contains("Name=TestApp"));
288+
assert!(data.contains("Comment=TestApp startup script"));
289+
assert!(data.contains("Exec=/opt/test-app --flag value"));
290+
assert!(data.contains("StartupNotify=false"));
291+
assert!(data.contains("Terminal=false"));
292+
}
293+
294+
#[test]
295+
fn test_build_systemd_service_data() {
296+
let data = build_systemd_service_data(
297+
"TestApp",
298+
"/opt/test-app",
299+
&vec!["--flag".into()],
300+
);
301+
302+
assert!(data.contains("Description=TestApp"));
303+
assert!(data.contains("After=default.target"));
304+
assert!(data.contains("ExecStart=/opt/test-app --flag"));
305+
assert!(data.contains("Restart=on-failure"));
306+
assert!(data.contains("WantedBy=default.target"));
307+
}
308+
}

src/macos.rs

Lines changed: 82 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -118,47 +118,12 @@ impl AutoLaunch {
118118
fs::create_dir(&dir)?;
119119
}
120120

121-
let mut args = vec![self.app_path.clone()];
122-
args.extend_from_slice(&self.args);
123-
124-
let section = args
125-
.iter()
126-
.map(|x| format!("<string>{}</string>", x))
127-
.collect::<String>();
128-
129-
let identifiers = self
130-
.bundle_identifiers
131-
.iter()
132-
.map(|x| format!("<string>{}</string>", x))
133-
.collect::<String>();
134-
135-
let extra_config = if !self.agent_extra_config.is_empty() {
136-
format!("{}\n ", self.agent_extra_config)
137-
} else {
138-
"".to_string()
139-
};
140-
141-
let data = format!(
142-
"{}\n{}\n\
143-
<plist version=\"1.0\">\n \
144-
<dict>\n \
145-
<key>Label</key>\n \
146-
<string>{}</string>\n \
147-
<key>AssociatedBundleIdentifiers</key>\n \
148-
<array>{}</array>\n \
149-
<key>ProgramArguments</key>\n \
150-
<array>{}</array>\n \
151-
<key>RunAtLoad</key>\n \
152-
<true/>\n \
153-
{}\
154-
</dict>\n\
155-
</plist>",
156-
r#"<?xml version="1.0" encoding="UTF-8"?>"#,
157-
r#"<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">"#,
158-
self.app_name,
159-
identifiers,
160-
section,
161-
extra_config
121+
let data = build_launch_agent_plist(
122+
&self.app_name,
123+
&self.app_path,
124+
&self.args,
125+
&self.bundle_identifiers,
126+
&self.agent_extra_config,
162127
);
163128
let _ = fs::File::create(self.get_file()?)?.write(data.as_bytes())?;
164129
Ok(())
@@ -293,3 +258,79 @@ fn exec_apple_script(cmd_suffix: &str) -> Result<Output> {
293258
.output()?;
294259
Ok(output)
295260
}
261+
262+
fn build_launch_agent_plist(
263+
app_name: &str,
264+
app_path: &str,
265+
args: &[String],
266+
bundle_identifiers: &[String],
267+
agent_extra_config: &str,
268+
) -> String {
269+
let mut full_args = vec![app_path.to_string()];
270+
full_args.extend_from_slice(args);
271+
272+
let section = full_args
273+
.iter()
274+
.map(|x| format!("<string>{}</string>", x))
275+
.collect::<String>();
276+
277+
let identifiers = bundle_identifiers
278+
.iter()
279+
.map(|x| format!("<string>{}</string>", x))
280+
.collect::<String>();
281+
282+
let extra_config = if !agent_extra_config.is_empty() {
283+
format!("{}\n ", agent_extra_config)
284+
} else {
285+
String::new()
286+
};
287+
288+
format!(
289+
"{}\n{}\n\
290+
<plist version=\"1.0\">\n \
291+
<dict>\n \
292+
<key>Label</key>\n \
293+
<string>{}</string>\n \
294+
<key>AssociatedBundleIdentifiers</key>\n \
295+
<array>{}</array>\n \
296+
<key>ProgramArguments</key>\n \
297+
<array>{}</array>\n \
298+
<key>RunAtLoad</key>\n \
299+
<true/>\n \
300+
{}\
301+
</dict>\n\
302+
</plist>",
303+
r#"<?xml version="1.0" encoding="UTF-8"?>"#,
304+
r#"<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">"#,
305+
app_name,
306+
identifiers,
307+
section,
308+
extra_config
309+
)
310+
}
311+
312+
#[cfg(test)]
313+
mod tests {
314+
use super::*;
315+
316+
#[test]
317+
fn test_build_launch_agent_plist() {
318+
let data = build_launch_agent_plist(
319+
"TestApp",
320+
"/Applications/TestApp.app",
321+
&vec!["--flag".into()],
322+
&vec!["com.example.testapp".into()],
323+
"<key>KeepAlive</key><true/>",
324+
);
325+
326+
assert!(data.contains("<key>Label</key>"));
327+
assert!(data.contains("<string>TestApp</string>"));
328+
assert!(data.contains("<key>AssociatedBundleIdentifiers</key>"));
329+
assert!(data.contains("<string>com.example.testapp</string>"));
330+
assert!(data.contains("<key>ProgramArguments</key>"));
331+
assert!(data.contains("<string>/Applications/TestApp.app</string>"));
332+
assert!(data.contains("<string>--flag</string>"));
333+
assert!(data.contains("<key>RunAtLoad</key>"));
334+
assert!(data.contains("<key>KeepAlive</key><true/>"));
335+
}
336+
}

src/windows.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,3 +191,26 @@ fn last_eight_bytes_all_zeros(bytes: &[u8]) -> std::result::Result<bool, &str> {
191191
Ok(bytes.iter().rev().take(8).all(|v| *v == 0u8))
192192
}
193193
}
194+
195+
#[cfg(test)]
196+
mod tests {
197+
use super::last_eight_bytes_all_zeros;
198+
199+
#[test]
200+
fn test_last_eight_bytes_all_zeros_true() {
201+
let data = [1u8, 2, 3, 4, 5, 0, 0, 0, 0, 0, 0, 0, 0];
202+
assert_eq!(last_eight_bytes_all_zeros(&data).unwrap(), true);
203+
}
204+
205+
#[test]
206+
fn test_last_eight_bytes_all_zeros_false() {
207+
let data = [0u8, 0, 0, 0, 0, 0, 0, 1];
208+
assert_eq!(last_eight_bytes_all_zeros(&data).unwrap(), false);
209+
}
210+
211+
#[test]
212+
fn test_last_eight_bytes_all_zeros_too_short() {
213+
let data = [0u8, 0, 0, 0, 0, 0, 0];
214+
assert!(last_eight_bytes_all_zeros(&data).is_err());
215+
}
216+
}

0 commit comments

Comments
 (0)