Migrate test asserts
[yangtools.git] / yang / yang-parser-impl / src / test / java / org / opendaylight / yangtools / yang / parser / impl / YangModelValidationTest.java
1 /*
2  * Copyright (c) 2013 Cisco Systems, Inc. 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.impl;
9
10 import static org.hamcrest.CoreMatchers.containsString;
11 import static org.junit.Assert.assertEquals;
12 import static org.junit.Assert.assertThat;
13 import static org.junit.Assert.fail;
14 import static org.mockito.Mockito.doReturn;
15 import static org.mockito.Mockito.mock;
16 import static org.mockito.Mockito.when;
17
18 import com.google.common.collect.Sets;
19
20 import java.text.SimpleDateFormat;
21 import java.util.ArrayList;
22 import java.util.Collections;
23 import java.util.Date;
24 import java.util.HashSet;
25 import java.util.List;
26
27 import org.antlr.v4.runtime.Token;
28 import org.antlr.v4.runtime.tree.ParseTree;
29 import org.antlr.v4.runtime.tree.TerminalNode;
30 import org.junit.Before;
31 import org.junit.Test;
32 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Augment_stmtContext;
33 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Deviate_add_stmtContext;
34 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Deviate_delete_stmtContext;
35 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Deviation_stmtContext;
36 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Import_stmtContext;
37 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Include_stmtContext;
38 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Module_stmtContext;
39 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Namespace_stmtContext;
40 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Prefix_stmtContext;
41 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Revision_date_stmtContext;
42 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Status_argContext;
43 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.StringContext;
44 import org.opendaylight.yangtools.yang.parser.util.YangValidationException;
45
46 public class YangModelValidationTest {
47
48     private YangModelBasicValidationListener valid;
49
50     @Before
51     public void setUp() {
52
53         valid = new YangModelBasicValidationListener();
54     }
55
56     @Test
57     public void testPrefixes() {
58         Prefix_stmtContext pref = mockStatement(Prefix_stmtContext.class, "unique1");
59         Module_stmtContext module = mockStatement(Module_stmtContext.class, "module1");
60         addChild(module, pref);
61
62         valid.enterPrefix_stmt(pref);
63
64         pref = mockStatement(Prefix_stmtContext.class, "unique1");
65         module = mockStatement(Module_stmtContext.class, "module1");
66         addChild(module, pref);
67
68         try {
69             valid.enterPrefix_stmt(pref);
70         } catch (Exception e) {
71             return;
72         }
73
74         fail("Validation Exception should have occured");
75     }
76
77     @Test
78     public void testNamespace() {
79
80         Namespace_stmtContext namespace = mockStatement(Namespace_stmtContext.class, "http://test.parsing.uri.com");
81         Module_stmtContext module = mockStatement(Module_stmtContext.class, "module1");
82         addChild(module, namespace);
83
84         valid.enterNamespace_stmt(namespace);
85
86         namespace = mockStatement(Namespace_stmtContext.class, "invalid uri");
87         module = mockStatement(Module_stmtContext.class, "module1");
88         addChild(module, namespace);
89
90         try {
91             valid.enterNamespace_stmt(namespace);
92         } catch (YangValidationException e) {
93             assertThat(e.getMessage(), containsString("Namespace:invalid uri cannot be parsed as URI"));
94             return;
95         }
96
97         fail("Validation Exception should have occured");
98     }
99
100     @Test
101     public void testImports() {
102         Import_stmtContext impor = mockImport("unique1", "p1");
103         Module_stmtContext mod = mockStatement(Module_stmtContext.class, "module1");
104         addChild(mod, impor);
105
106         valid.enterImport_stmt(impor);
107
108         impor = mockImport("unique1", "p2");
109         mod = mockStatement(Module_stmtContext.class, "module1");
110         addChild(mod, impor);
111
112         try {
113             valid.enterImport_stmt(impor);
114         } catch (YangValidationException e) {
115             assertThat(e.getMessage(), containsString("Import:unique1 not unique"));
116             return;
117         }
118
119         fail("Validation Exception should have occured");
120     }
121
122     @Test
123     public void testIncludes() {
124         Include_stmtContext incl = mockInclude("unique1");
125         Module_stmtContext mod = mockStatement(Module_stmtContext.class, "module1");
126         addChild(mod, incl);
127         valid.enterInclude_stmt(incl);
128
129         incl = mockInclude("unique1");
130         mod = mockStatement(Module_stmtContext.class, "module1");
131         addChild(mod, incl);
132
133         try {
134             valid.enterInclude_stmt(incl);
135         } catch (YangValidationException e) {
136             assertThat(e.getMessage(), containsString("Include:unique1 not unique in (sub)module"));
137             return;
138         }
139
140         fail("Validation Exception should have occured");
141     }
142
143     @Test
144     public void testIdentifierMatching() {
145         List<String> ids = new ArrayList<String>();
146         // valid
147         ids.add("_ok98-.87.-.8...88-asdAD");
148         ids.add("AA.bcd");
149         ids.add("a");
150         // invalid
151         ids.add("9aa");
152         ids.add("-");
153         ids.add(".");
154
155         int thrown = 0;
156         for (String id : ids) {
157             try {
158                 Module_stmtContext module = mock(Module_stmtContext.class);
159                 Token token = mock(Token.class);
160                 when(module.getStart()).thenReturn(token);
161                 BasicValidations.checkIdentifierInternal(module, id);
162             } catch (YangValidationException e) {
163                 thrown++;
164             }
165         }
166
167         assertEquals(3, thrown);
168     }
169
170     @Test(expected = YangValidationException.class)
171     public void testAugument() {
172         Augment_stmtContext augument = mockStatement(Augment_stmtContext.class, "/a:*abc/a:augument1");
173         Module_stmtContext mod1 = mockStatement(Module_stmtContext.class, "mod1");
174         addChild(mod1, augument);
175
176         Token token = mock(Token.class);
177         when(augument.getStart()).thenReturn(token);
178
179         try {
180             valid.enterAugment_stmt(augument);
181         } catch (YangValidationException e) {
182             assertThat(
183                     e.getMessage(),
184                     containsString("Schema node id:/a:*abc/a:augument1 not in required format, details:Prefixed id:a:*abc not in required format"));
185             throw e;
186         }
187     }
188
189     @Test
190     public void testDeviate() {
191         Deviation_stmtContext ctx = mockStatement(Deviation_stmtContext.class, "deviations");
192         Deviate_add_stmtContext add = mockStatement(Deviate_add_stmtContext.class, "add");
193         Deviate_delete_stmtContext del = mockStatement(Deviate_delete_stmtContext.class, "delete");
194
195         addChild(ctx, add);
196         addChild(ctx, del);
197
198         valid.enterDeviation_stmt(ctx);
199
200         HashSet<Class<? extends ParseTree>> types = Sets.newHashSet();
201         types.add(Deviate_add_stmtContext.class);
202         types.add(Deviate_delete_stmtContext.class);
203
204         int count = ValidationUtil.countPresentChildrenOfType(ctx, types);
205         assertEquals(2, count);
206     }
207
208     @Test(expected = YangValidationException.class)
209     public void testStatus() throws Exception {
210         Status_argContext status = mockStatement(Status_argContext.class, "unknown");
211         try {
212             valid.enterStatus_arg(status);
213         } catch (YangValidationException e) {
214             assertThat(e.getMessage(), containsString("illegal value for Status statement, only permitted:"));
215             throw e;
216         }
217     }
218
219     private Import_stmtContext mockImport(final String name, final String prefixName) {
220         Import_stmtContext impor = mockStatement(Import_stmtContext.class, name);
221
222         Prefix_stmtContext prefix = mockStatement(Prefix_stmtContext.class, prefixName);
223         Revision_date_stmtContext revDate = mockStatement(Revision_date_stmtContext.class, getFormattedDate());
224
225         addChild(impor, prefix);
226         addChild(impor, revDate);
227         return impor;
228     }
229
230     static String getFormattedDate() {
231         return new SimpleDateFormat("yyyy-MM-dd").format(new Date());
232     }
233
234     private Include_stmtContext mockInclude(final String name) {
235         Include_stmtContext incl = mockStatement(Include_stmtContext.class, name);
236
237         Revision_date_stmtContext revDate = mockStatement(Revision_date_stmtContext.class, getFormattedDate());
238
239         addChild(incl, revDate);
240         return incl;
241     }
242
243     static void mockName(final ParseTree stmt, final String name) {
244         doReturn(1).when(stmt).getChildCount();
245
246         TerminalNode terminalNode = mock(TerminalNode.class);
247         doReturn(name).when(terminalNode).getText();
248
249         StringContext nameCtx = mock(StringContext.class);
250         doReturn(nameCtx).when(stmt).getChild(0);
251         doReturn(terminalNode).when(nameCtx).getChild(0);
252         doReturn(name).when(terminalNode).getText();
253
254         doReturn(Collections.singletonList(terminalNode)).when(nameCtx).STRING();
255     }
256
257     static <T extends ParseTree> T mockStatement(final Class<T> stmtType, final String name) {
258         T stmt = stmtType.cast(mock(stmtType));
259
260         doReturn(0).when(stmt).getChildCount();
261
262         if (name != null) {
263             mockName(stmt, name);
264         }
265         return stmt;
266     }
267
268     static void addChild(final ParseTree parent, final ParseTree child) {
269         int childCount = parent.getChildCount() + 1;
270         doReturn(childCount).when(parent).getChildCount();
271         doReturn(child).when(parent).getChild(childCount - 1);
272         doReturn(parent).when(child).getParent();
273     }
274
275 }