View Javadoc
1   /**
2    * Logback: the reliable, generic, fast and flexible logging framework.
3    * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
4    *
5    * This program and the accompanying materials are dual-licensed under
6    * either the terms of the Eclipse Public License v1.0 as published by
7    * the Eclipse Foundation
8    *
9    *   or (per the licensee's choosing)
10   *
11   * under the terms of the GNU Lesser General Public License version 2.1
12   * as published by the Free Software Foundation.
13   */
14  package ch.qos.logback.core.subst;
15  
16  import ch.qos.logback.core.spi.ScanException;
17  import org.junit.jupiter.api.Test;
18  
19  import java.util.ArrayList;
20  
21  import static org.junit.jupiter.api.Assertions.assertEquals;
22  import static org.junit.jupiter.api.Assertions.fail;
23  
24  /**
25   *
26   */
27  public class ParserTest {
28  
29      @Test
30      public void literal() throws ScanException {
31          Tokenizer tokenizer = new Tokenizer("abc");
32          Parser parser = new Parser(tokenizer.tokenize());
33          Node node = parser.parse();
34          Node witness = new Node(Node.Type.LITERAL, "abc");
35          assertEquals(witness, node);
36      }
37  
38      @Test
39      public void literalWithAccolade0() throws ScanException {
40          Tokenizer tokenizer = new Tokenizer("{}");
41          Parser parser = new Parser(tokenizer.tokenize());
42          Node node = parser.parse();
43          Node witness = new Node(Node.Type.LITERAL, "{");
44          witness.next = new Node(Node.Type.LITERAL, "}");
45          assertEquals(witness, node);
46      }
47  
48      @Test
49      public void literalWithAccolade1() throws ScanException {
50          Tokenizer tokenizer = new Tokenizer("%x{a}");
51          Parser parser = new Parser(tokenizer.tokenize());
52          Node node = parser.parse();
53          Node witness = new Node(Node.Type.LITERAL, "%x");
54          Node t = witness.next = new Node(Node.Type.LITERAL, "{");
55          t.next = new Node(Node.Type.LITERAL, "a");
56          t = t.next;
57          t.next = new Node(Node.Type.LITERAL, "}");
58          assertEquals(witness, node);
59      }
60  
61      @Test
62      public void literalWithTwoAccolades() throws ScanException {
63          Tokenizer tokenizer = new Tokenizer("%x{y} %a{b} c");
64  
65          Parser parser = new Parser(tokenizer.tokenize());
66          Node node = parser.parse();
67          Node witness = new Node(Node.Type.LITERAL, "%x");
68  
69          Node t = witness.next = new Node(Node.Type.LITERAL, "{");
70          t.next = new Node(Node.Type.LITERAL, "y");
71          t = t.next;
72  
73          t.next = new Node(Node.Type.LITERAL, "}");
74          t = t.next;
75  
76          t.next = new Node(Node.Type.LITERAL, " %a");
77          t = t.next;
78  
79          t.next = new Node(Node.Type.LITERAL, "{");
80          t = t.next;
81  
82          t.next = new Node(Node.Type.LITERAL, "b");
83          t = t.next;
84  
85          t.next = new Node(Node.Type.LITERAL, "}");
86          t = t.next;
87  
88          t.next = new Node(Node.Type.LITERAL, " c");
89  
90          node.dump();
91          System.out.println("");
92          assertEquals(witness, node);
93      }
94  
95      @Test
96      public void variable() throws ScanException {
97          Tokenizer tokenizer = new Tokenizer("${abc}");
98          Parser parser = new Parser(tokenizer.tokenize());
99          Node node = parser.parse();
100         Node witness = new Node(Node.Type.VARIABLE, new Node(Node.Type.LITERAL, "abc"));
101         assertEquals(witness, node);
102     }
103 
104     @Test
105     public void literalVariableLiteral() throws ScanException {
106         Tokenizer tokenizer = new Tokenizer("a${b}c");
107         Parser parser = new Parser(tokenizer.tokenize());
108         Node node = parser.parse();
109         Node witness = new Node(Node.Type.LITERAL, "a");
110         witness.next = new Node(Node.Type.VARIABLE, new Node(Node.Type.LITERAL, "b"));
111         witness.next.next = new Node(Node.Type.LITERAL, "c");
112         assertEquals(witness, node);
113     }
114 
115     // /LOGBACK-744
116     @Test
117     public void withColon() throws ScanException {
118         Tokenizer tokenizer = new Tokenizer("a:${b}");
119         Parser parser = new Parser(tokenizer.tokenize());
120         Node node = parser.parse();
121         Node witness = new Node(Node.Type.LITERAL, "a");
122         Node t = witness.next = new Node(Node.Type.LITERAL, ":");
123         t.next = new Node(Node.Type.VARIABLE, new Node(Node.Type.LITERAL, "b"));
124         assertEquals(witness, node);
125     }
126 
127     @Test
128     public void withNoClosingBraces() throws ScanException {
129         Tokenizer tokenizer = new Tokenizer("a${b");
130         Parser parser = new Parser(tokenizer.tokenize());
131         try {
132             parser.parse();
133         } catch (IllegalArgumentException e) {
134             assertEquals("All tokens consumed but was expecting \"}\"", e.getMessage());
135             return;
136         }
137         fail();
138     }
139 
140     @Test
141     public void nested() throws ScanException {
142         Tokenizer tokenizer = new Tokenizer("a${b${c}}d");
143         Parser parser = new Parser(tokenizer.tokenize());
144         Node node = parser.parse();
145         Node witness = new Node(Node.Type.LITERAL, "a");
146         Node bLiteralNode = new Node(Node.Type.LITERAL, "b");
147         Node cLiteralNode = new Node(Node.Type.LITERAL, "c");
148         Node bVariableNode = new Node(Node.Type.VARIABLE, bLiteralNode);
149         Node cVariableNode = new Node(Node.Type.VARIABLE, cLiteralNode);
150         bLiteralNode.next = cVariableNode;
151 
152         witness.next = bVariableNode;
153         witness.next.next = new Node(Node.Type.LITERAL, "d");
154         assertEquals(witness, node);
155     }
156 
157     @Test
158     public void withDefault() throws ScanException {
159         Tokenizer tokenizer = new Tokenizer("${b:-c}");
160         Parser parser = new Parser(tokenizer.tokenize());
161         Node node = parser.parse();
162         Node witness = new Node(Node.Type.VARIABLE, new Node(Node.Type.LITERAL, "b"));
163         witness.defaultPart = new Node(Node.Type.LITERAL, "c");
164         assertEquals(witness, node);
165     }
166 
167     @Test
168     public void withEmptryDefault() throws ScanException {
169         Tokenizer tokenizer = new Tokenizer("${b:-}");
170         Parser parser = new Parser(tokenizer.tokenize());
171         Node node = parser.parse();
172         Node witness = new Node(Node.Type.VARIABLE, new Node(Node.Type.LITERAL, "b"));
173         witness.defaultPart = new Node(Node.Type.LITERAL, "");
174         assertEquals(witness, node);
175     }
176 
177 
178     @Test
179     public void defaultSeparatorOutsideOfAVariable() throws ScanException {
180         Tokenizer tokenizer = new Tokenizer("{a:-b}");
181         Parser parser = new Parser(tokenizer.tokenize());
182         Node node = parser.parse();
183 
184         dump(node);
185         Node witness = new Node(Node.Type.LITERAL, "{");
186         Node t = witness.next = new Node(Node.Type.LITERAL, "a");
187 
188         t.next = new Node(Node.Type.LITERAL, ":-");
189         t = t.next;
190 
191         t.next = new Node(Node.Type.LITERAL, "b");
192         t = t.next;
193 
194         t.next = new Node(Node.Type.LITERAL, "}");
195 
196         assertEquals(witness, node);
197     }
198 
199     @Test
200     public void emptyTokenListDoesNotThrowNullPointerException() throws ScanException {
201         // An empty token list would be returned from Tokenizer.tokenize()
202         // if it were constructed with an empty string. The parser should
203         // be able to handle this.
204         Parser parser = new Parser(new ArrayList<Token>());
205         parser.parse();
206     }
207 
208     private void dump(Node node) {
209         while (node != null) {
210             System.out.println(node.toString());
211             node = node.next;
212         }
213     }
214 
215 }