xref: /OpenGrok/opengrok-indexer/src/test/java/org/opengrok/indexer/analysis/haskell/HaskellXrefTest.java (revision 52d10766ed1db3b0fd2c59a0da7292a32f244b50)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * See LICENSE.txt included in this distribution for the specific
9  * language governing permissions and limitations under the License.
10  *
11  * When distributing Covered Code, include this CDDL HEADER in each
12  * file and include the License file at LICENSE.txt.
13  * If applicable, add the following below this CDDL HEADER, with the
14  * fields enclosed by brackets "[]" replaced with your own identifying
15  * information: Portions Copyright [yyyy] [name of copyright owner]
16  *
17  * CDDL HEADER END
18  */
19 
20 /*
21  * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved.
22  * Portions Copyright (c) 2017, 2018, Chris Fraire <cfraire@me.com>.
23  */
24 package org.opengrok.indexer.analysis.haskell;
25 
26 import java.io.BufferedReader;
27 import java.io.ByteArrayOutputStream;
28 import java.io.IOException;
29 import java.io.InputStream;
30 import java.io.InputStreamReader;
31 import java.io.PrintStream;
32 import java.io.StringReader;
33 import java.io.StringWriter;
34 import java.io.Writer;
35 import java.nio.charset.StandardCharsets;
36 
37 import org.junit.jupiter.api.Test;
38 import org.opengrok.indexer.analysis.AbstractAnalyzer;
39 import org.opengrok.indexer.analysis.CtagsReader;
40 import org.opengrok.indexer.analysis.Definitions;
41 import org.opengrok.indexer.analysis.WriteXrefArgs;
42 import org.opengrok.indexer.analysis.Xrefer;
43 
44 import static org.junit.jupiter.api.Assertions.assertEquals;
45 import static org.junit.jupiter.api.Assertions.assertNotNull;
46 import static org.opengrok.indexer.util.CustomAssertions.assertLinesEqual;
47 import static org.opengrok.indexer.util.StreamUtils.copyStream;
48 
49 /**
50  * Tests the {@link HaskellXref} class.
51  *
52  * @author Harry Pan
53  */
54 public class HaskellXrefTest {
55 
56     @Test
basicTest()57     public void basicTest() throws IOException {
58         String s = "putStrLn \"Hello, world!\"";
59         Writer w = new StringWriter();
60         HaskellAnalyzerFactory fac = new HaskellAnalyzerFactory();
61         AbstractAnalyzer analyzer = fac.getAnalyzer();
62         WriteXrefArgs xargs = new WriteXrefArgs(new StringReader(s), w);
63         Xrefer xref = analyzer.writeXref(xargs);
64         assertLinesEqual("Haskell basicTest",
65             "<a class=\"l\" name=\"1\" href=\"#1\">1</a>" +
66             "<a href=\"/source/s?defs=putStrLn\" class=\"intelliWindow-symbol\"" +
67             " data-definition-place=\"undefined-in-file\">putStrLn</a>" +
68             " <span class=\"s\">&quot;Hello, world!&quot;</span>\n",
69                 w.toString());
70         assertEquals(1, xref.getLOC(), "Haskell LOC");
71     }
72 
writeHaskellXref(InputStream is, PrintStream os, Definitions defs)73     private static int writeHaskellXref(InputStream is, PrintStream os,
74         Definitions defs) throws IOException {
75         os.println("<!DOCTYPE html><html lang=\"en\"><head><meta http-equiv=\"content-type\" content=\"text/html;charset=UTF-8\" />"
76                 + "<link rel=\"stylesheet\" type=\"text/css\" "
77                 + "href=\"http://localhost:8080/source/default/style.css\" /><title>Haskell Xref Test</title></head>");
78         os.println("<body><div id=\"src\"><pre>");
79         Writer w = new StringWriter();
80         HaskellAnalyzerFactory fac = new HaskellAnalyzerFactory();
81         AbstractAnalyzer analyzer = fac.getAnalyzer();
82         WriteXrefArgs args = new WriteXrefArgs(new InputStreamReader(is, StandardCharsets.UTF_8), w);
83         args.setDefs(defs);
84         Xrefer xref = analyzer.writeXref(args);
85         os.print(w.toString());
86         os.println("</pre></div></body></html>");
87         return xref.getLOC();
88     }
89 
90     @Test
sampleTest()91     public void sampleTest() throws IOException {
92         // load sample source
93         InputStream sampleInputStream = getClass().getClassLoader().getResourceAsStream(
94                 "analysis/haskell/sample.hs");
95         ByteArrayOutputStream sampleOutputStream = new ByteArrayOutputStream();
96 
97         Definitions defs = new Definitions();
98         defs.addTag(6, "x'y'", "functions",
99             "x'y' = let f' = 1; g'h = 2 in f' + g'h", 0, 0);
100         int actLOC;
101         try {
102             actLOC = writeHaskellXref(sampleInputStream, new PrintStream(sampleOutputStream), defs);
103         } finally {
104             sampleInputStream.close();
105             sampleOutputStream.close();
106         }
107 
108         // load expected xref
109         InputStream expectedInputStream = getClass().getClassLoader().getResourceAsStream(
110                 "analysis/haskell/sampleXrefExpected.html");
111         ByteArrayOutputStream expectedOutputSteam = new ByteArrayOutputStream();
112         try {
113             byte[] buffer = new byte[8192];
114             int numBytesRead;
115             do {
116                 numBytesRead = expectedInputStream.read(buffer, 0, buffer.length);
117                 if (numBytesRead > 0) {
118                     expectedOutputSteam.write(buffer, 0, numBytesRead);
119                 }
120             } while (numBytesRead >= 0);
121         } finally {
122             expectedInputStream.close();
123             expectedOutputSteam.close();
124         }
125 
126         String[] actual = new String(sampleOutputStream.toByteArray(), StandardCharsets.UTF_8).split("\\r?\\n");
127         String[] expected = new String(expectedOutputSteam.toByteArray(), StandardCharsets.UTF_8).split("\\r?\\n");
128         assertLinesEqual("Haskell sampleTest()", expected, actual);
129         assertEquals(3, actLOC, "Haskell LOC");
130     }
131 
132     @Test
sampleTest2()133     public void sampleTest2() throws IOException {
134         writeAndCompare("analysis/haskell/sample2.hs",
135             "analysis/haskell/sample2_xref.html",
136             getTagsDefinitions(), 198);
137     }
138 
139     @Test
shouldCloseTruncatedStringSpan()140     public void shouldCloseTruncatedStringSpan() throws IOException {
141         writeAndCompare("analysis/haskell/truncated.hs",
142             "analysis/haskell/truncated_xref.html",
143             null, 1);
144     }
145 
writeAndCompare(String sourceResource, String resultResource, Definitions defs, int expLOC)146     private void writeAndCompare(String sourceResource, String resultResource,
147         Definitions defs, int expLOC) throws IOException {
148 
149         ByteArrayOutputStream baos = new ByteArrayOutputStream();
150 
151         InputStream res = getClass().getClassLoader().getResourceAsStream(
152             sourceResource);
153         assertNotNull(res, sourceResource + " should get-as-stream");
154         int actLOC = writeHaskellXref(res, new PrintStream(baos), defs);
155         res.close();
156 
157         InputStream exp = getClass().getClassLoader().getResourceAsStream(
158             resultResource);
159         assertNotNull(exp, resultResource + " should get-as-stream");
160         byte[] expbytes = copyStream(exp);
161         exp.close();
162         baos.close();
163 
164         String ostr = new String(baos.toByteArray(), StandardCharsets.UTF_8);
165         String[] gotten = ostr.split("\\r?\\n");
166 
167         String estr = new String(expbytes, StandardCharsets.UTF_8);
168         String[] expected = estr.split("\n");
169 
170         assertLinesEqual("Haskell xref", expected, gotten);
171         assertEquals(expLOC, actLOC, "Haskell LOC");
172     }
173 
getTagsDefinitions()174     private Definitions getTagsDefinitions() throws IOException {
175         InputStream res = getClass().getClassLoader().getResourceAsStream(
176             "analysis/haskell/sampletags");
177         assertNotNull(res, "though sampletags should stream,");
178 
179         BufferedReader in = new BufferedReader(new InputStreamReader(res, StandardCharsets.UTF_8));
180 
181         CtagsReader rdr = new CtagsReader();
182         String line;
183         while ((line = in.readLine()) != null) {
184             rdr.readLine(line);
185         }
186         return rdr.getDefinitions();
187     }
188 }
189