Migrate yang-data-impl to JUnit5
[yangtools.git] / data / yang-data-impl / src / test / java / org / opendaylight / yangtools / yang / data / impl / codec / YT1442Test.java
1 /*
2  * Copyright (c) 2022 PANTHEON.tech, 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.data.impl.codec;
9
10 import static org.junit.jupiter.api.Assertions.assertEquals;
11 import static org.junit.jupiter.api.Assertions.assertInstanceOf;
12 import static org.junit.jupiter.api.Assertions.assertThrows;
13
14 import java.util.List;
15 import org.eclipse.jdt.annotation.NonNull;
16 import org.junit.jupiter.api.BeforeAll;
17 import org.junit.jupiter.api.Test;
18 import org.opendaylight.yangtools.yang.common.Decimal64;
19 import org.opendaylight.yangtools.yang.common.ErrorSeverity;
20 import org.opendaylight.yangtools.yang.common.ErrorTag;
21 import org.opendaylight.yangtools.yang.common.ErrorType;
22 import org.opendaylight.yangtools.yang.common.QName;
23 import org.opendaylight.yangtools.yang.data.api.codec.YangInvalidValueException;
24 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
25 import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
26
27 class YT1442Test {
28     private static DecimalStringCodec codec;
29
30     @BeforeAll
31     static void beforeClass() {
32         final var foo = YangParserTestUtils.parseYang("""
33             module yt1442 {
34               namespace yt1442;
35               prefix yt1442;
36
37               leaf foo {
38                 type decimal64 {
39                   fraction-digits 2;
40                   range 10.0..100.0 {
41                     error-app-tag model-defined-app-tag;
42                     error-message model-defined-message;
43                   }
44                 }
45               }
46             }""")
47             .getDataChildByName(QName.create("yt1442", "foo"));
48         codec = assertInstanceOf(DecimalStringCodec.class,
49             TypeDefinitionAwareCodec.from(assertInstanceOf(LeafSchemaNode.class, foo).getType()));
50     }
51
52     @Test
53     void testTen() {
54         final var ten = codec.deserialize("10.00");
55         assertDecimal(1000, ten);
56         assertEquals("10.0", codec.serialize(ten));
57     }
58
59     @Test
60     void testFifty() {
61         final var fifty = codec.deserialize("50.00");
62         assertDecimal(5000, fifty);
63         assertEquals("50.0", codec.serialize(fifty));
64     }
65
66     @Test
67     void testHundred() {
68         final var hundred = codec.deserialize("100.00");
69         assertDecimal(10000, hundred);
70         assertEquals("100.0", codec.serialize(hundred));
71     }
72
73     @Test
74     void testNegativeOutOfRange() {
75         assertYIVE("Value '-10.0' is not in required ranges [[10.0..100.0]]", "-10.00");
76         assertYIVE("Value '-50.0' is not in required ranges [[10.0..100.0]]", "-50.00");
77         assertYIVE("Value '-100.0' is not in required ranges [[10.0..100.0]]", "-100.00");
78     }
79
80     @Test
81     void testPositiveOutOfRange() {
82         assertYIVE("Value '9.99' is not in required ranges [[10.0..100.0]]", "9.99");
83         assertYIVE("Value '100.01' is not in required ranges [[10.0..100.0]]", "100.01");
84     }
85
86     @Test
87     void testTooLargeFractionPart() {
88         final var ex = assertThrows(IllegalArgumentException.class, () -> codec.deserialize("100.001"));
89         assertEquals("Value '100.001' does not match required fraction-digits", ex.getMessage());
90         final var cause = assertInstanceOf(ArithmeticException.class, ex.getCause());
91         assertEquals("Decreasing scale of 100.001 to 2 requires rounding", cause.getMessage());
92     }
93
94     @Test
95     void testTooLargeIntegralPart() {
96         final var ex = assertThrows(IllegalArgumentException.class, () -> codec.deserialize("92233720368547759.0"));
97         assertEquals("Value '92233720368547759.0' does not match required fraction-digits", ex.getMessage());
98         final var cause = assertInstanceOf(ArithmeticException.class, ex.getCause());
99         assertEquals("Increasing scale of 92233720368547759.0 to 2 would overflow", cause.getMessage());
100     }
101
102     private static void assertDecimal(final long unscaledValue, final Object obj) {
103         final var actual = assertInstanceOf(Decimal64.class, obj);
104         assertEquals(2, actual.scale());
105         assertEquals(unscaledValue, actual.unscaledValue());
106     }
107
108     private static void assertYIVE(final String expectedMessage, final @NonNull String input) {
109         final var ex = assertThrows(YangInvalidValueException.class, () -> codec.deserialize(input));
110         assertEquals(expectedMessage, ex.getMessage());
111
112         final var errors = ex.getNetconfErrors();
113         assertEquals(1, errors.size());
114         final var error = errors.get(0);
115         assertEquals(ErrorSeverity.ERROR, error.severity());
116         assertEquals(ErrorType.APPLICATION, error.type());
117         assertEquals(ErrorTag.INVALID_VALUE, error.tag());
118         assertEquals("model-defined-app-tag", error.appTag());
119         assertEquals("model-defined-message", error.message());
120         assertEquals(List.of(), error.info());
121     }
122 }