Another round of Sonar warnings fixes
[yangtools.git] / parser / yang-parser-rfc7950 / src / test / java / org / opendaylight / yangtools / yang / parser / rfc7950 / stmt / pattern / Bug5410Test.java
1 /*
2  * Copyright (c) 2018 Pantheon Technologies, s.r.o. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.yangtools.yang.parser.rfc7950.stmt.pattern;
9
10 import static org.junit.jupiter.api.Assertions.assertEquals;
11 import static org.junit.jupiter.api.Assertions.assertFalse;
12 import static org.junit.jupiter.api.Assertions.assertTrue;
13
14 import java.io.ByteArrayOutputStream;
15 import java.io.PrintStream;
16 import java.io.UnsupportedEncodingException;
17 import java.nio.charset.StandardCharsets;
18 import java.util.List;
19 import org.junit.jupiter.api.Test;
20
21 class Bug5410Test {
22     @Test
23     void testCaret() {
24         testPattern("^", "\\^");
25     }
26
27     @Test
28     void testTextCaret() {
29         testPattern("abc^", "abc\\^");
30     }
31
32     @Test
33     void testTextDollar() {
34         testPattern("abc$", "abc\\$");
35     }
36
37     @Test
38     void testCaretCaret() {
39         testPattern("^^", "\\^\\^");
40     }
41
42     @Test
43     void testCaretDollar() {
44         testPattern("^$", "\\^\\$");
45     }
46
47     @Test
48     void testDot() {
49         testPattern(".", ".");
50     }
51
52     @Test
53     void testNotColon() {
54         testPattern("[^:]+", "[^:]+");
55     }
56
57     @Test
58     void testDollar() {
59         testPattern("$", "\\$");
60     }
61
62     @Test
63     void testDollarOneDollar() {
64         testPattern("$1$", "\\$1\\$");
65     }
66
67     @Test
68     void testDollarPercentRange() {
69         testPattern("[$-%]+", "[$-%]+");
70     }
71
72     @Test
73     void testDollarRange() {
74         testPattern("[$$]+", "[$$]+");
75     }
76
77     @Test
78     void testDollarCaretRange() {
79         testPattern("[$^]+", "[$^]+");
80     }
81
82     @Test
83     void testSimple() {
84         testPattern("abc", "abc");
85     }
86
87     @Test
88     void testDotPlus() {
89         testPattern(".+", ".+");
90     }
91
92     @Test
93     void testDotStar() {
94         testPattern(".*", ".*");
95     }
96
97     @Test
98     void testSimpleOptional() {
99         testPattern("a?", "a?");
100     }
101
102     @Test
103     void testRangeOptional() {
104         testPattern("[a-z]?", "[a-z]?");
105     }
106
107     @Test
108     void testInvalidXSDRegexes() throws UnsupportedEncodingException {
109         testInvalidPattern("$^a^[$^\\]", "Unclosed character class");
110         testInvalidPattern("$(\\)", "Unclosed group");
111     }
112
113     @Test
114     void testJavaPattern() {
115         testPattern("^[$^]+$", List.of("$^", "^", "$"), List.of("\\", "a"));
116         testPattern("^[^$-^]$", List.of("a", "_", "#"), List.of("%", "^", "$", "]", "\\"));
117     }
118
119     @Test
120     void testJavaRegexFromXSD() {
121         testPattern("^[^:]+$", "^(?:\\^[^:]+\\$)$", List.of("^a$", "^abc$"), List.of("abc$", "^abc", "^a:bc$"));
122         testPattern("^[$^]$", "^(?:\\^[$^]\\$)$", List.of("^^$", "^$$"), List.of("^^", "^$", "$^", "$$"));
123         testPattern("[$-%]+", "^(?:[$-%]+)$", List.of("$", "%", "%$"), List.of("$-", "$-%", "-", "^"));
124         testPattern("[$-&]+", "^(?:[$-&]+)$", List.of("$", "%&", "%$", "$%&"), List.of("#", "$-&", "'"));
125
126         testPattern("[a-z&&[^m-p]]+", "^(?:[a-z&&[^m-p]]+)$", List.of("a", "z", "az"), List.of("m", "anz", "o"));
127         testPattern("^[\\[-b&&[^^-a]]+$", "^(?:\\^[\\[-b&&[^^-a]]+\\$)$",
128             List.of("^[$", "^\\$", "^]$", "^b$"), List.of("^a$", "^^$", "^_$"));
129
130         // FIXME: YANGTOOLS-887: these patterns are not translated correctly, "&&" is a different construct in XSD
131         //        testPattern("[^^-~&&[^$-^]]", "^(?:[^^-~&&[^$-^]])$",
132         //            List.of("!", "\"", "#"), List.of("a", "A", "z", "Z", "$", "%", "^", "}"));
133         //        testPattern("\\\\\\[^[^^-~&&[^$-^]]", "^(?:\\\\\\[\\^[^^-~&&[^$-^]])$",
134         //            List.of("\\[^ ", "\\[^!", "\\[^\"", "\\[^#"),
135         //            List.of("\\[^a", "\\[^A", "\\[^z", "\\[^Z", "\\[^$", "\\[^%", "\\[^^", "\\[^}"));
136         //        testPattern("^\\[^\\\\[^^-b&&[^\\[-\\]]]\\]^", "^(?:\\^\\[\\^\\\\[^^-b&&[^\\[-\\]]]\\]\\^)$",
137         //            List.of("^[^\\c]^", "^[^\\Z]^"),
138         //            List.of("^[^\\[]^", "^[^\\\\]^", "^[^\\]]^", "^[^\\^]^", "^[^\\_]^", "^[^\\b]^"));
139         //        testPattern("[\\^]$", "^(?:[\\^]\\$)$",
140         //            List.of("^$"), List.of("^", "$", "$^", "\\", "\\^", "\\^\\", "\\^\\$"));
141     }
142
143     @SuppressWarnings("checkstyle:regexpSinglelineJava")
144     private static void testInvalidPattern(final String xsdRegex, final String expectedMessage) {
145         final PrintStream stdout = System.out;
146         final ByteArrayOutputStream output = new ByteArrayOutputStream();
147         System.setOut(new PrintStream(output, true, StandardCharsets.UTF_8));
148
149         RegexUtils.getJavaRegexFromXSD(xsdRegex);
150
151         final String testLog = output.toString();
152         assertTrue(testLog.contains(expectedMessage));
153         System.setOut(stdout);
154     }
155
156     private static boolean testMatch(final String javaRegex, final String value) {
157         return value.matches(javaRegex);
158     }
159
160     private static void testPattern(final String xsdRegex, final String unanchoredJavaRegex) {
161         testPattern(xsdRegex, "^(?:" + unanchoredJavaRegex + ")$", List.of(), List.of());
162     }
163
164     private static void testPattern(final String javaRegex, final List<String> positiveMatches,
165             final List<String> negativeMatches) {
166         for (var value : positiveMatches) {
167             assertTrue(testMatch(javaRegex, value),
168                 "Value '" + value + "' does not match java regex '" + javaRegex + "'");
169         }
170         for (var value : negativeMatches) {
171             assertFalse(testMatch(javaRegex, value), "Value '" + value + "' matches java regex '" + javaRegex + "'");
172         }
173     }
174
175     private static void testPattern(final String xsdRegex, final String expectedJavaRegex,
176             final List<String> positiveMatches, final List<String> negativeMatches) {
177         final String javaRegexFromXSD = RegexUtils.getJavaRegexFromXSD(xsdRegex);
178         assertEquals(expectedJavaRegex, javaRegexFromXSD);
179
180         for (var value : positiveMatches) {
181             assertTrue(testMatch(javaRegexFromXSD, value),
182                 "Value '" + value + "' does not match java regex '" + javaRegexFromXSD + "'");
183         }
184         for (var value : negativeMatches) {
185             assertFalse(testMatch(javaRegexFromXSD, value),
186                 "Value '" + value + "' matches java regex '" + javaRegexFromXSD + "'");
187         }
188     }
189 }