View Javadoc
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 }