001/*
002 * Copyright 2005,2009 Ivan SZKIBA
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.ini4j.test;
017
018import org.ini4j.sample.BeanEventSample;
019import org.ini4j.sample.BeanSample;
020import org.ini4j.sample.DumpSample;
021import org.ini4j.sample.Dwarf;
022import org.ini4j.sample.DwarfBean;
023import org.ini4j.sample.Dwarfs;
024import org.ini4j.sample.DwarfsBean;
025import org.ini4j.sample.FromSample;
026import org.ini4j.sample.IniSample;
027import org.ini4j.sample.ListenerSample;
028import org.ini4j.sample.NoImportSample;
029import org.ini4j.sample.PyReadSample;
030import org.ini4j.sample.ReadPrimitiveSample;
031import org.ini4j.sample.ReadStringSample;
032import org.ini4j.sample.StreamSample;
033import org.ini4j.sample.ToSample;
034
035import org.ini4j.tutorial.BeanTutorial;
036import org.ini4j.tutorial.IniTutorial;
037import org.ini4j.tutorial.OneMinuteTutorial;
038import org.ini4j.tutorial.OptTutorial;
039import org.ini4j.tutorial.PrefsTutorial;
040import org.ini4j.tutorial.RegTutorial;
041import org.ini4j.tutorial.WindowsRegistryTutorial;
042
043import org.junit.Test;
044
045import org.junit.runner.RunWith;
046
047import org.junit.runners.Parameterized;
048import org.junit.runners.Parameterized.Parameters;
049
050import java.io.File;
051import java.io.FileInputStream;
052import java.io.FileOutputStream;
053import java.io.FileReader;
054import java.io.FileWriter;
055import java.io.InputStream;
056import java.io.InputStreamReader;
057import java.io.LineNumberReader;
058import java.io.PrintStream;
059import java.io.PrintWriter;
060import java.io.Reader;
061
062import java.lang.reflect.Method;
063
064import java.nio.charset.Charset;
065
066import java.util.Arrays;
067import java.util.Collection;
068import java.util.regex.Matcher;
069import java.util.regex.Pattern;
070
071@RunWith(Parameterized.class)
072public class SampleRunnerTest
073{
074    private static final String DOC_PATH = "generated-site/apt";
075    private static final String JAVA_SUFFIX = ".java";
076    private static final String PACKAGE_INFO = "package-info" + JAVA_SUFFIX;
077    private static final String APT_SUFFIX = ".apt";
078    private static final String APT_INDEX = "index" + APT_SUFFIX;
079    private static final String CODE_BEGIN = "\n+----+\n";
080    private static final String CODE_END = "+----+\n\n";
081    private static File _documentDir;
082
083    static
084    {
085        System.setProperty("java.util.prefs.PreferencesFactory", "org.ini4j.IniPreferencesFactory");
086        _documentDir = new File(Helper.getBuildDirectory(), DOC_PATH);
087        _documentDir.mkdirs();
088        try
089        {
090            document(sourceFile(Dwarf.class), "//");
091            document(sourceFile(DwarfBean.class), "//");
092            document(sourceFile(Dwarfs.class), "//");
093            document(sourceFile(DwarfsBean.class), "//");
094            document(sourceFile(IniTutorial.class.getPackage()), "//");
095            document(sourceFile(IniSample.class.getPackage()), "//");
096        }
097        catch (Exception x)
098        {
099            throw new IllegalStateException(x);
100        }
101    }
102
103    private final Class _clazz;
104    private final File _sourceFile;
105
106    public SampleRunnerTest(Class sampleClass) throws Exception
107    {
108        _clazz = sampleClass;
109        _sourceFile = sourceFile(_clazz);
110    }
111
112    @Parameters public static Collection data()
113    {
114        return Arrays.asList(
115                new Object[][]
116                {
117
118                    // samples
119                    { ReadStringSample.class },
120                    { ReadPrimitiveSample.class },
121                    { IniSample.class },
122                    { StreamSample.class },
123                    { DumpSample.class },
124                    { NoImportSample.class },
125                    { ListenerSample.class },
126                    { BeanSample.class },
127                    { BeanEventSample.class },
128                    { FromSample.class },
129                    { ToSample.class },
130                    { PyReadSample.class },
131
132                    // tutorials
133                    { OneMinuteTutorial.class },
134                    { IniTutorial.class },
135                    { RegTutorial.class },
136                    { WindowsRegistryTutorial.class },
137                    { OptTutorial.class },
138                    { BeanTutorial.class },
139                    { PrefsTutorial.class },
140                });
141    }
142
143    @Test public void test() throws Exception
144    {
145        System.out.println("Executing " + _clazz.getName());
146        PrintStream saved = System.out;
147        File tmp = File.createTempFile(getClass().getSimpleName(), ".out");
148        PrintStream out = new PrintStream(new FileOutputStream(tmp));
149
150        System.setOut(out);
151        try
152        {
153            execute();
154        }
155        finally
156        {
157            System.setOut(saved);
158            out.flush();
159        }
160
161        document(_sourceFile, "//");
162        index(source2document(_sourceFile), source2index(_clazz));
163        if (tmp.length() > 0)
164        {
165            append(tmp);
166        }
167
168        tmp.delete();
169    }
170
171    private static void document(File src, String comment) throws Exception
172    {
173        Pattern docPattern = Pattern.compile(String.format("^\\s*%s\\|(.*)$", comment));
174        Pattern beginPattern = Pattern.compile(String.format("^\\s*%s\\{.*$", comment));
175        Pattern endPattern = Pattern.compile(String.format("^\\s*%s\\}.*$", comment));
176        LineNumberReader reader = new LineNumberReader(openReader(src));
177        PrintWriter writer = new PrintWriter(new FileWriter(source2document(src)));
178        boolean in = false;
179
180        for (String line = reader.readLine(); line != null; line = reader.readLine())
181        {
182            if (in)
183            {
184                if (endPattern.matcher(line).matches())
185                {
186                    in = false;
187                    writer.println(CODE_END);
188                }
189                else
190                {
191                    writer.println(line);
192                }
193            }
194            else
195            {
196                if (beginPattern.matcher(line).matches())
197                {
198                    in = true;
199                    writer.println(CODE_BEGIN);
200                }
201                else
202                {
203                    Matcher m = docPattern.matcher(line);
204
205                    if (m.matches())
206                    {
207                        writer.println(m.group(1));
208                    }
209                }
210            }
211        }
212
213        reader.close();
214        writer.close();
215    }
216
217    private static void index(File src, File dst) throws Exception
218    {
219        LineNumberReader reader = new LineNumberReader(new FileReader(src));
220        PrintWriter writer = new PrintWriter(new FileWriter(dst, true));
221        String name = src.getName().replace(".apt", ".html");
222        boolean h1 = false;
223        boolean p = false;
224
225        for (String line = reader.readLine(); line != null; line = reader.readLine())
226        {
227            if (line.length() == 0)
228            {
229                if (p)
230                {
231                    writer.println();
232
233                    break;
234                }
235                else if (h1)
236                {
237                    p = true;
238                }
239            }
240            else
241            {
242                if (Character.isSpaceChar(line.charAt(0)))
243                {
244                    if (p)
245                    {
246                        writer.println(line);
247                    }
248                }
249                else
250                {
251                    if (!h1)
252                    {
253                        h1 = true;
254                        writer.print(String.format(" *{{{%s}%s}}", name, line));
255                        writer.println();
256                        writer.println();
257                    }
258                }
259            }
260        }
261
262        writer.close();
263        reader.close();
264    }
265
266    private static Reader openReader(File src) throws Exception
267    {
268        InputStream stream = new FileInputStream(src);
269        byte[] head = new byte[2];
270        int n = stream.read(head);
271
272        stream.close();
273        Charset charset;
274
275        if ((n == 2) && (head[0] == -1) && (head[1] == -2))
276        {
277            charset = Charset.forName("UnicodeLittle");
278        }
279        else
280        {
281            charset = Charset.forName("UTF-8");
282        }
283
284        return new InputStreamReader(new FileInputStream(src), charset);
285    }
286
287    private static File source2document(File sourceFile) throws Exception
288    {
289        String name = sourceFile.getName();
290        File dir = new File(_documentDir, sourceFile.getParentFile().getName());
291
292        dir.mkdir();
293
294        return new File(dir, name.equals(PACKAGE_INFO) ? APT_INDEX : (name + APT_SUFFIX));
295    }
296
297    private static File source2index(Class clazz) throws Exception
298    {
299        return source2document(sourceFile(clazz.getPackage()));
300    }
301
302    private static File sourceFile(Class clazz) throws Exception
303    {
304        return Helper.getSourceFile(clazz.getName().replaceAll("\\.", "/") + JAVA_SUFFIX);
305    }
306
307    private static File sourceFile(Package pkg) throws Exception
308    {
309        return Helper.getSourceFile(pkg.getName().replaceAll("\\.", "/") + '/' + PACKAGE_INFO);
310    }
311
312    private void append(File stdout) throws Exception
313    {
314        PrintWriter writer = new PrintWriter(new FileWriter(source2document(_sourceFile), true));
315
316        writer.println("\n Standard output:\n");
317        writer.println(CODE_BEGIN);
318        LineNumberReader reader = new LineNumberReader(new FileReader(stdout));
319
320        for (String line = reader.readLine(); line != null; line = reader.readLine())
321        {
322            writer.println(line);
323        }
324
325        writer.println(CODE_END);
326        reader.close();
327        writer.close();
328    }
329
330    @SuppressWarnings("unchecked")
331    private void execute() throws Exception
332    {
333        Method main = _clazz.getMethod("main", String[].class);
334        String[] args;
335
336        try
337        {
338            File argument = new File(_sourceFile.getParentFile(), (String) _clazz.getField("FILENAME").get(null));
339
340            document(argument, "[#;!]");
341            args = new String[] { argument.getCanonicalPath() };
342        }
343        catch (NoSuchFieldException x)
344        {
345            args = new String[] {};
346        }
347
348        main.invoke(null, (Object) args);
349    }
350}