2 * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
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
8 package org.opendaylight.yangtools.yang.stmt.retest;
10 import static org.hamcrest.CoreMatchers.containsString;
11 import static org.junit.Assert.assertThat;
12 import static org.junit.Assert.fail;
13 import static org.mockito.Mockito.doReturn;
14 import static org.mockito.Mockito.mock;
15 import static org.mockito.Mockito.when;
16 import java.text.SimpleDateFormat;
17 import java.util.Collections;
18 import java.util.Date;
19 import org.antlr.v4.runtime.Token;
20 import org.antlr.v4.runtime.tree.ParseTree;
21 import org.antlr.v4.runtime.tree.TerminalNode;
22 import org.junit.Before;
23 import org.junit.Test;
24 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Augment_stmtContext;
25 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Import_stmtContext;
26 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Include_stmtContext;
27 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Module_stmtContext;
28 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Namespace_stmtContext;
29 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Prefix_stmtContext;
30 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Revision_date_stmtContext;
31 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Status_argContext;
32 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.StringContext;
33 //import org.opendaylight.yangtools.yang.parser.impl.BasicValidations;
34 //import org.opendaylight.yangtools.yang.parser.impl.ValidationUtil;
35 import org.opendaylight.yangtools.yang.parser.impl.YangModelBasicValidationListener;
36 import org.opendaylight.yangtools.yang.parser.util.YangValidationException;
38 public class YangModelValidationTest {
40 private YangModelBasicValidationListener valid;
45 valid = new YangModelBasicValidationListener();
49 public void testPrefixes() {
50 Prefix_stmtContext pref = mockStatement(Prefix_stmtContext.class, "unique1");
51 Module_stmtContext module = mockStatement(Module_stmtContext.class, "module1");
52 addChild(module, pref);
54 valid.enterPrefix_stmt(pref);
56 pref = mockStatement(Prefix_stmtContext.class, "unique1");
57 module = mockStatement(Module_stmtContext.class, "module1");
58 addChild(module, pref);
61 valid.enterPrefix_stmt(pref);
62 } catch (Exception e) {
66 fail("Validation Exception should have occured");
70 public void testNamespace() {
72 Namespace_stmtContext namespace = mockStatement(Namespace_stmtContext.class, "http://test.parsing.uri.com");
73 Module_stmtContext module = mockStatement(Module_stmtContext.class, "module1");
74 addChild(module, namespace);
76 valid.enterNamespace_stmt(namespace);
78 namespace = mockStatement(Namespace_stmtContext.class, "invalid uri");
79 module = mockStatement(Module_stmtContext.class, "module1");
80 addChild(module, namespace);
83 valid.enterNamespace_stmt(namespace);
84 } catch (YangValidationException e) {
85 assertThat(e.getMessage(), containsString("Namespace:invalid uri cannot be parsed as URI"));
89 fail("Validation Exception should have occured");
93 public void testImports() {
94 Import_stmtContext impor = mockImport("unique1", "p1");
95 Module_stmtContext mod = mockStatement(Module_stmtContext.class, "module1");
98 valid.enterImport_stmt(impor);
100 impor = mockImport("unique1", "p2");
101 mod = mockStatement(Module_stmtContext.class, "module1");
102 addChild(mod, impor);
105 valid.enterImport_stmt(impor);
106 } catch (YangValidationException e) {
107 assertThat(e.getMessage(), containsString("Import:unique1 not unique"));
111 fail("Validation Exception should have occured");
115 public void testIncludes() {
116 Include_stmtContext incl = mockInclude("unique1");
117 Module_stmtContext mod = mockStatement(Module_stmtContext.class, "module1");
119 valid.enterInclude_stmt(incl);
121 incl = mockInclude("unique1");
122 mod = mockStatement(Module_stmtContext.class, "module1");
126 valid.enterInclude_stmt(incl);
127 } catch (YangValidationException e) {
128 assertThat(e.getMessage(), containsString("Include:unique1 not unique in (sub)module"));
132 fail("Validation Exception should have occured");
136 // public void testIdentifierMatching() {
137 // List<String> ids = new ArrayList<String>();
139 // ids.add("_ok98-.87.-.8...88-asdAD");
140 // ids.add("AA.bcd");
148 // for (String id : ids) {
150 // Module_stmtContext module = mock(Module_stmtContext.class);
151 // Token token = mock(Token.class);
152 // when(module.getStart()).thenReturn(token);
153 // BasicValidat ions.checkIdentifierInternal(module, id);
154 // } catch (YangValidationException e) {
159 // assertEquals(3, thrown);
162 @Test(expected = YangValidationException.class)
163 public void testAugument() {
164 Augment_stmtContext augument = mockStatement(Augment_stmtContext.class, "/a:*abc/a:augument1");
165 Module_stmtContext mod1 = mockStatement(Module_stmtContext.class, "mod1");
166 addChild(mod1, augument);
168 Token token = mock(Token.class);
169 when(augument.getStart()).thenReturn(token);
172 valid.enterAugment_stmt(augument);
173 } catch (YangValidationException e) {
176 containsString("Schema node id:/a:*abc/a:augument1 not in required format, details:Prefixed id:a:*abc not in required format"));
182 // public void testDeviate() {
183 // Deviation_stmtContext ctx = mockStatement(Deviation_stmtContext.class, "deviations");
184 // Deviate_add_stmtContext add = mockStatement(Deviate_add_stmtContext.class, "add");
185 // Deviate_delete_stmtContext del = mockStatement(Deviate_delete_stmtContext.class, "delete");
187 // addChild(ctx, add);
188 // addChild(ctx, del);
190 // valid.enterDeviation_stmt(ctx);
192 // HashSet<Class<? extends ParseTree>> types = Sets.newHashSet();
193 // types.add(Deviate_add_stmtContext.class);
194 // types.add(Deviate_delete_stmtContext.class);
196 // int count = ValidationUtil.countPresentChildrenOfType(ctx, types);
197 // assertEquals(2, count);
200 @Test(expected = YangValidationException.class)
201 public void testStatus() throws Exception {
202 Status_argContext status = mockStatement(Status_argContext.class, "unknown");
204 valid.enterStatus_arg(status);
205 } catch (YangValidationException e) {
206 assertThat(e.getMessage(), containsString("illegal value for Status statement, only permitted:"));
211 private static Import_stmtContext mockImport(final String name, final String prefixName) {
212 Import_stmtContext impor = mockStatement(Import_stmtContext.class, name);
214 Prefix_stmtContext prefix = mockStatement(Prefix_stmtContext.class, prefixName);
215 Revision_date_stmtContext revDate = mockStatement(Revision_date_stmtContext.class, getFormattedDate());
217 addChild(impor, prefix);
218 addChild(impor, revDate);
222 static String getFormattedDate() {
223 return new SimpleDateFormat("yyyy-MM-dd").format(new Date());
226 private static Include_stmtContext mockInclude(final String name) {
227 Include_stmtContext incl = mockStatement(Include_stmtContext.class, name);
229 Revision_date_stmtContext revDate = mockStatement(Revision_date_stmtContext.class, getFormattedDate());
231 addChild(incl, revDate);
235 static void mockName(final ParseTree stmt, final String name) {
236 doReturn(1).when(stmt).getChildCount();
238 TerminalNode terminalNode = mock(TerminalNode.class);
239 doReturn(name).when(terminalNode).getText();
241 StringContext nameCtx = mock(StringContext.class);
242 doReturn(nameCtx).when(stmt).getChild(0);
243 doReturn(terminalNode).when(nameCtx).getChild(0);
244 doReturn(name).when(terminalNode).getText();
246 doReturn(Collections.singletonList(terminalNode)).when(nameCtx).STRING();
249 static <T extends ParseTree> T mockStatement(final Class<T> stmtType, final String name) {
250 T stmt = stmtType.cast(mock(stmtType));
252 doReturn(0).when(stmt).getChildCount();
255 mockName(stmt, name);
260 static void addChild(final ParseTree parent, final ParseTree child) {
261 int childCount = parent.getChildCount() + 1;
262 doReturn(childCount).when(parent).getChildCount();
263 doReturn(child).when(parent).getChild(childCount - 1);
264 doReturn(parent).when(child).getParent();