001package edu.pdx.cs.joy.family; 002 003import org.junit.jupiter.api.Test; 004import org.junit.jupiter.api.io.TempDir; 005 006import java.io.File; 007import java.io.PrintWriter; 008import java.io.StringWriter; 009import java.lang.reflect.Field; 010import java.lang.reflect.Modifier; 011import java.util.StringTokenizer; 012 013import static org.junit.jupiter.api.Assertions.fail; 014 015/** 016 * This class tests the behavior of the {@link AddPerson} program to 017 * ensure that I don't again suffer the kind of embarrassment I 018 * suffered in the Spring of 2002 when my students found a bunch of 019 * bugs in my code. 020 */ 021public class AddPersonTest { 022 023 private static final boolean DEBUG = 024 Boolean.getBoolean("AddPersonTest.DEBUG"); 025 026 /** 027 * Invokes the main method of AddPerson with the given command line 028 * string 029 */ 030 private void addPerson(String cmdLine) { 031 if (DEBUG) { 032 System.out.println("\n" + cmdLine + "\n"); 033 } 034 035 // Create an array of Strings to send to main 036 StringTokenizer st = new StringTokenizer(cmdLine); 037 String[] args = new String[st.countTokens()]; 038 for (int i = 0; st.hasMoreTokens(); i++) { 039 args[i] = st.nextToken(); 040 } 041 042 AddPerson.main(args); 043 reset(AddPerson.class); 044 } 045 046 /** 047 * "Resets" all of the static fields in a given class to their 048 * default value 049 */ 050 private static void reset(Class c) { 051 Field[] fields = c.getDeclaredFields(); 052 for (int i = 0; i < fields.length; i++) { 053 Field field = fields[i]; 054 if (!Modifier.isFinal(field.getModifiers())) { 055 field.setAccessible(true); 056 try { 057 reset(field); 058 059 } catch (IllegalAccessException ex) { 060 StringWriter sw = new StringWriter(); 061 sw.write("While accessing field " + field + ": "); 062 ex.printStackTrace(new PrintWriter(sw, true)); 063 fail(sw.toString()); 064 } 065 } 066 } 067 } 068 069 /** 070 * "Resets" the value of the given static field to its default value 071 */ 072 private static void reset(Field field) 073 throws IllegalAccessException { 074 075 Class type = field.getType(); 076 if (type.equals(boolean.class)) { 077 field.set(null, Boolean.FALSE); 078 079 } else if (type.equals(char.class)) { 080 field.set(null, '\0' ); 081 082 } else if (type.equals(byte.class)) { 083 field.set(null, (byte) 0 ); 084 085 } else if (type.equals(short.class)) { 086 field.set(null, (short) 0 ); 087 088 } else if (type.equals(int.class)) { 089 field.set(null, 0 ); 090 091 } else if (type.equals(long.class)) { 092 field.set(null, 0L ); 093 094 } else if (type.equals(float.class)) { 095 field.set(null, 0.0f ); 096 097 } else if (type.equals(double.class)) { 098 field.set(null, 0.0 ); 099 100 } else { 101 assert Object.class.isAssignableFrom(type) : type; 102 field.set(null, null); 103 } 104 } 105 106 /** 107 * Invokes the main method of NoteMarriage with the given command line 108 * string 109 */ 110 private void noteMarriage(String cmdLine) { 111 if (DEBUG) { 112 System.out.println("\n" + cmdLine + "\n"); 113 } 114 115 // Create an array of Strings to send to main 116 StringTokenizer st = new StringTokenizer(cmdLine); 117 String[] args = new String[st.countTokens()]; 118 for (int i = 0; st.hasMoreTokens(); i++) { 119 args[i] = st.nextToken(); 120 } 121 122 NoteMarriage.main(args); 123 reset(NoteMarriage.class); 124 } 125 126 /** 127 * Create a family tree that describes Dave's family. 128 * 129 * @param fileOption 130 * The kind of file to use 131 */ 132 private void createDavesFamily(File tempDir, String fileOption) { 133 // Create a temp file to write the family tree to 134 File file = new File(tempDir, "DavesFamily" + fileOption); 135 136 // XML parser complains about empty file, so delete it before we 137 // start 138 file.delete(); 139 140 String fileName = file.getAbsolutePath(); 141 142 143 addPerson(fileOption + fileName + 144 " 1 male David Michael Whitlock"); 145 146 addPerson(fileOption + "-parentOf 1 " + fileName + 147 " 2 male Stanley Jay Whitlock Feb 27, 1948"); 148 149 addPerson(fileOption + "-parentOf 1 " + fileName + 150 " 3 female Carolyn Joyce Granger May 17, 1945"); 151 152 noteMarriage(fileOption + "-date Jul 12, 1969 " + fileName + 153 " 2 3 "); 154 155 // If we get this far, delete the file 156 file.delete(); 157 } 158 159 //////// Test cases 160 161 @Test 162 public void testText(@TempDir File tempDir) { 163 createDavesFamily(tempDir, ""); 164 } 165 166 @Test 167 public void testXml(@TempDir File tempDir) { 168 createDavesFamily(tempDir, "-xml "); 169 } 170}