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