1   package junit;
2   
3   import java.io.ByteArrayOutputStream;
4   import java.io.File;
5   import java.io.IOException;
6   import java.io.InputStream;
7   import java.io.OutputStream;
8   import java.io.PrintStream;
9   
10  import junit.framework.TestCase;
11  import net.sourceforge.jparam.ConstantRegistry;
12  import net.sourceforge.jparam.JParam;
13  import net.sourceforge.jparam.conversion.ConverterRegistry;
14  import net.sourceforge.jparam.conversion.creators.CreatorRegistry;
15  import net.sourceforge.jparam.conversion.creators.ObjectCreator;
16  import net.sourceforge.jparam.output.SerializerRegistry;
17  import net.sourceforge.jparam.paramset.Param;
18  import net.sourceforge.jparam.paramset.ParamSet;
19  import net.sourceforge.jparam.typename.TypeNameRegistry;
20  
21  public abstract class ParamSetTestCase extends TestCase {
22  	protected boolean DEBUG = false;
23  
24  	public static String NL = System.getProperty("line.separator");
25  
26  	public static String N = "\n";
27  
28  	public static String OUTPUT_END = N + ";" + NL;
29  
30  	private void resetJParam() {
31  		ConstantRegistry.clearSingleton();
32  		TypeNameRegistry.clearSingleton();
33  		ObjectCreator.clearSingleton();
34  		CreatorRegistry.clearSingleton();
35  		SerializerRegistry.clearSingleton();
36  		ConverterRegistry.clearSingleton();
37  		JParam.init();
38  	}
39  
40  	PrintStream oldOut = System.out;
41  
42  	PrintStream oldErr = System.err;
43  
44  	ByteArrayOutputStream baos = new ByteArrayOutputStream();
45  
46  	PrintStream out = new PrintStream(baos);
47  
48  	PrintStream redirectErr = new PrintStream(new RedirectOutputStream(oldErr,
49  			baos), true);
50  
51  	PrintStream redirectOut = new PrintStream(new RedirectOutputStream(oldOut,
52  			baos), true);
53  
54  	protected ParamSet ps;
55  
56  	protected void setUp() throws Exception {
57  		super.setUp();
58  		resetJParam();
59  
60  		System.setOut(redirectOut);
61  		System.setErr(redirectErr);
62  		ps = new ParamSet();
63  	}
64  
65  	// override this and return the parameters needed to be initialized into the
66  	// ParamSet
67  	abstract public Param[] getInitParams() throws Exception;
68  
69  	abstract public String[] getInput();
70  
71  	public boolean isOutputNeeded() {
72  		return true;
73  	}
74  
75  	// override this in order to do something before input is called
76  	public void preInput() {
77  	}
78  
79  	// override this in order to do something before output is called
80  	public void preOutput() {
81  	}
82  
83  	// override this in order to do something after output is called
84  	public void postOutput() {
85  	}
86  
87  	// if Input is supposed to throw an exception override this
88  	public Exception getExpectedInputError() {
89  		return null;
90  	}
91  
92  	// if you want the inputed parameters to be verified override this
93  	public Object[] getExpectedParameterValues() {
94  		return null;
95  	}
96  
97  	// if you want to run the output return the expected string here
98  	public String getExpectedOutput() throws Exception {
99  		String fullTestName = this.getClass().getName();
100 		fullTestName = fullTestName
101 				.substring(fullTestName.lastIndexOf('.') + 1);
102 
103 		String testDir = fullTestName.substring(0, fullTestName.indexOf('$'));
104 		String testName = fullTestName.substring(testDir.length() + 1);
105 		String testFileName = testDir + File.separator + "output"
106 				+ File.separator + testDir + "_" + testName + ".out";
107 		InputStream outputFile = getClass().getClassLoader()
108 				.getResourceAsStream(testFileName);
109 
110 		String outputString = null;
111 		if (outputFile != null) {
112 			try {
113 				ByteArrayOutputStream baos = new ByteArrayOutputStream();
114 				while (outputFile.available() > 0) {
115 					baos.write(outputFile.read());
116 				}
117 				outputString = baos.toString();
118 			} catch (IOException e) {
119 				e.printStackTrace();
120 			}
121 		} else {
122 			outputString = "Test output file not found: " + testFileName;
123 		}
124 		return outputString;
125 	}
126 
127 	public void testParamSet() throws Throwable {
128 		try {
129 			Exception inputException = null;
130 			try {
131 				Param[] params = getInitParams();
132 				assertNotNull(params);
133 
134 				for (int i = 0; i < params.length; i++) {
135 					ps.addParam(params[i]);
136 				}
137 
138 				String[] inputStrings = getInput();
139 				assertNotNull(inputStrings);
140 
141 				preInput();
142 				ps.input(inputStrings);
143 			} catch (Exception e) {
144 				inputException = e;
145 				System.out.println("Got following error - ");
146 				System.out.println(e.getMessage());
147 				if (DEBUG)
148 					e.printStackTrace(System.out);
149 			}
150 
151 			Exception expectedException = getExpectedInputError();
152 
153 			//			assertFalse((expectedException == null) ^ (inputException ==
154 			// null));
155 
156 			if (expectedException != null) {
157 				assertEquals(expectedException.getMessage(), inputException
158 						.getMessage());
159 			}
160 
161 			if (isOutputNeeded() && inputException == null) {
162 				preOutput();
163 				ps.output(System.out);
164 				postOutput();
165 			}
166 
167 			String expectedOutput = getExpectedOutput();
168 			String actualOutput = baos.toString();
169 			actualOutput = dos2Unix(actualOutput);
170 			expectedOutput = dos2Unix(expectedOutput);
171 			assertEquals(expectedOutput, actualOutput);
172 		} catch (Exception e) {
173 			oldErr.println(baos.toString());
174 			oldErr.println("Unhandled exception performing test: ");
175 			e.printStackTrace(oldErr);
176 			throw e;
177 		} finally {
178 			System.setOut(oldOut);
179 			System.setErr(oldErr);
180 		}
181 	}
182 
183 	private String dos2Unix(String input) {
184 		if (input.indexOf('\r') < 0) {
185 			return input;
186 		}
187 
188 		StringBuffer res = new StringBuffer();
189 		for (int i = 0; i < input.length(); i++) {
190 			char c = input.charAt(i);
191 			if (c != '\r') {
192 				res.append(c);
193 			}
194 		}
195 
196 		return res.toString();
197 	}
198 
199 	private class RedirectOutputStream extends OutputStream {
200 		OutputStream ps1, ps2;
201 
202 		public RedirectOutputStream(OutputStream ps1, OutputStream ps2) {
203 			this.ps1 = ps1;
204 			this.ps2 = ps2;
205 		}
206 
207 		public void write(int b) throws IOException {
208 			ps1.write(b);
209 			ps2.write(b);
210 		}
211 
212 	}
213 }