1 /*
2 * Copyright 2011-2026 the original author or authors.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * You may obtain a copy of the License at
10 *
11 * https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 */
18 package com.hazendaz.maven.makeself;
19
20 import java.lang.reflect.Field;
21 import java.nio.file.Path;
22
23 import org.apache.maven.plugin.logging.Log;
24 import org.junit.jupiter.api.Assumptions;
25 import org.junit.jupiter.api.Test;
26 import org.junit.jupiter.api.extension.ExtendWith;
27 import org.junit.jupiter.api.io.TempDir;
28 import org.mockito.Mock;
29 import org.mockito.Mockito;
30 import org.mockito.junit.jupiter.MockitoExtension;
31
32 /**
33 * The Class GitMojoTest.
34 */
35 @ExtendWith(MockitoExtension.class)
36 class GitMojoTest {
37
38 /** Temporary directory for test files. */
39 @TempDir
40 Path tempDir;
41
42 /** Mock Maven log. */
43 @Mock
44 private Log log;
45
46 /**
47 * Sets a private field on the given object via reflection, walking up the class hierarchy as needed.
48 *
49 * @param obj
50 * the object
51 * @param fieldName
52 * the field name
53 * @param value
54 * the value to set
55 *
56 * @throws Exception
57 * if the field cannot be found or set
58 */
59 private static void setField(final Object obj, final String fieldName, final Object value) throws Exception {
60 final Field field = findField(obj.getClass(), fieldName);
61 field.setAccessible(true);
62 field.set(obj, value);
63 }
64
65 /**
66 * Finds a declared field by name, walking the class hierarchy.
67 *
68 * @param clazz
69 * the class to start from
70 * @param name
71 * the field name
72 *
73 * @return the field
74 *
75 * @throws NoSuchFieldException
76 * if no field with the given name is found
77 */
78 private static Field findField(final Class<?> clazz, final String name) throws NoSuchFieldException {
79 try {
80 return clazz.getDeclaredField(name);
81 } catch (final NoSuchFieldException e) {
82 if (clazz.getSuperclass() != null) {
83 return findField(clazz.getSuperclass(), name);
84 }
85 throw e;
86 }
87 }
88
89 /**
90 * Test skip execution logs message and returns without error.
91 *
92 * @throws Exception
93 * the exception
94 */
95 @Test
96 void testSkipExecution() throws Exception {
97 final GitMojo mojo = new GitMojo();
98 mojo.setLog(log);
99 setField(mojo, "skip", true);
100
101 mojo.execute();
102
103 Mockito.verify(log).info("Makeself git is skipped");
104 }
105
106 /**
107 * Test execute on non-Windows platform logs the skipping message and returns without error.
108 *
109 * @throws Exception
110 * the exception
111 */
112 @Test
113 void testNonWindowsExecution() throws Exception {
114 Assumptions.assumeFalse(AbstractGitMojo.WINDOWS, "Test only applicable on non-Windows platforms");
115
116 final GitMojo mojo = new GitMojo();
117 mojo.setLog(log);
118
119 mojo.execute();
120
121 Mockito.verify(log).info("Portable git is only applicable on Windows; skipping on this platform");
122 }
123
124 /**
125 * Test execute on a simulated Windows platform with an existing git installation at gitPath. Verifies that the
126 * existing git path is used without downloading portable git, and the final gitPath is logged.
127 *
128 * @throws Exception
129 * the exception
130 */
131 @Test
132 void testWindowsSimulatedExistingGitPath() throws Exception {
133 Assumptions.assumeFalse(AbstractGitMojo.WINDOWS, "Windows-simulation test is only run on non-Windows");
134
135 // Anonymous subclass that simulates Windows platform detection
136 final GitMojo mojo = new GitMojo() {
137 @Override
138 protected boolean isWindows() {
139 return true;
140 }
141 };
142 mojo.setLog(log);
143
144 // Set gitPath to tempDir which is guaranteed to exist
145 setField(mojo, "gitPath", tempDir.toString());
146
147 mojo.execute();
148
149 Mockito.verify(log).info(Mockito.startsWith("Using existing 'Git' found at "));
150 Mockito.verify(log).info(Mockito.startsWith("Portable git is available at: "));
151 }
152
153 }