ParserTest.java
/*
* Logback: the reliable, generic, fast and flexible logging framework.
* Copyright (C) 1999-2026, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v2.0 as published by
* the Eclipse Foundation
*
* or (per the licensee's choosing)
*
* under the terms of the GNU Lesser General Public License version 2.1
* as published by the Free Software Foundation.
*/
package ch.qos.logback.core.pattern.parser;
import java.util.ArrayList;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import ch.qos.logback.core.Context;
import ch.qos.logback.core.ContextBase;
import ch.qos.logback.core.pattern.FormatInfo;
import ch.qos.logback.core.spi.ScanException;
import ch.qos.logback.core.status.testUtil.StatusChecker;
public class ParserTest {
String BARE = Token.BARE_COMPOSITE_KEYWORD_TOKEN.getValue().toString();
Context context = new ContextBase();
@Test
public void testBasic() throws Exception {
Parser<Object> p = new Parser<>("hello");
Node t = p.parse();
Assertions.assertEquals(Node.LITERAL, t.getType());
Assertions.assertEquals("hello", t.getValue());
}
@Test
public void testKeyword() throws Exception {
{
Parser<Object> p = new Parser<>("hello%xyz");
Node t = p.parse();
Node witness = new Node(Node.LITERAL, "hello");
witness.next = new SimpleKeywordNode("xyz");
Assertions.assertEquals(witness, t);
}
{
Parser<Object> p = new Parser<>("hello%xyz{x}");
Node t = p.parse();
Node witness = new Node(Node.LITERAL, "hello");
SimpleKeywordNode n = new SimpleKeywordNode("xyz");
List<String> optionList = new ArrayList<String>();
optionList.add("x");
n.setOptions(optionList);
witness.next = n;
Assertions.assertEquals(witness, t);
}
}
@Test
public void testComposite() throws Exception {
{
Parser<Object> p = new Parser<>("hello%(%child)");
Node t = p.parse();
Node witness = new Node(Node.LITERAL, "hello");
CompositeNode composite = new CompositeNode(BARE);
Node child = new SimpleKeywordNode("child");
composite.setChildNode(child);
witness.next = composite;
// System.out.println("w:" + witness);
// System.out.println(t);
Assertions.assertEquals(witness, t);
}
// System.out.println("testRecursive part 2");
{
Parser<Object> p = new Parser<>("hello%(%child )");
Node t = p.parse();
Node witness = new Node(Node.LITERAL, "hello");
CompositeNode composite = new CompositeNode(BARE);
Node child = new SimpleKeywordNode("child");
composite.setChildNode(child);
witness.next = composite;
child.next = new Node(Node.LITERAL, " ");
Assertions.assertEquals(witness, t);
}
{
Parser<Object> p = new Parser<>("hello%(%child %h)");
Node t = p.parse();
Node witness = new Node(Node.LITERAL, "hello");
CompositeNode composite = new CompositeNode(BARE);
Node child = new SimpleKeywordNode("child");
composite.setChildNode(child);
child.next = new Node(Node.LITERAL, " ");
child.next.next = new SimpleKeywordNode("h");
witness.next = composite;
Assertions.assertEquals(witness, t);
}
{
Parser<Object> p = new Parser<>("hello%(%child %h) %m");
Node t = p.parse();
Node witness = new Node(Node.LITERAL, "hello");
CompositeNode composite = new CompositeNode(BARE);
Node child = new SimpleKeywordNode("child");
composite.setChildNode(child);
child.next = new Node(Node.LITERAL, " ");
child.next.next = new SimpleKeywordNode("h");
witness.next = composite;
composite.next = new Node(Node.LITERAL, " ");
composite.next.next = new SimpleKeywordNode("m");
Assertions.assertEquals(witness, t);
}
{
Parser<Object> p = new Parser<>("hello%( %child \\(%h\\) ) %m");
Node t = p.parse();
Node witness = new Node(Node.LITERAL, "hello");
CompositeNode composite = new CompositeNode(BARE);
Node child = new Node(Node.LITERAL, " ");
composite.setChildNode(child);
Node c = child;
c = c.next = new SimpleKeywordNode("child");
c = c.next = new Node(Node.LITERAL, " (");
c = c.next = new SimpleKeywordNode("h");
c = c.next = new Node(Node.LITERAL, ") ");
witness.next = composite;
composite.next = new Node(Node.LITERAL, " ");
composite.next.next = new SimpleKeywordNode("m");
Assertions.assertEquals(witness, t);
}
}
@Test
public void testNested() throws Exception {
{
Parser<Object> p = new Parser<>("%top %(%child%(%h))");
Node t = p.parse();
Node witness = new SimpleKeywordNode("top");
Node w = witness.next = new Node(Node.LITERAL, " ");
CompositeNode composite = new CompositeNode(BARE);
w = w.next = composite;
Node child = new SimpleKeywordNode("child");
composite.setChildNode(child);
composite = new CompositeNode(BARE);
child.next = composite;
composite.setChildNode(new SimpleKeywordNode("h"));
Assertions.assertEquals(witness, t);
}
}
@Test
public void testFormattingInfo() throws Exception {
{
Parser<Object> p = new Parser<>("%45x");
Node t = p.parse();
FormattingNode witness = new SimpleKeywordNode("x");
witness.setFormatInfo(new FormatInfo(45, Integer.MAX_VALUE));
Assertions.assertEquals(witness, t);
}
{
Parser<Object> p = new Parser<>("%4.5x");
Node t = p.parse();
FormattingNode witness = new SimpleKeywordNode("x");
witness.setFormatInfo(new FormatInfo(4, 5));
Assertions.assertEquals(witness, t);
}
{
Parser<Object> p = new Parser<>("%-4.5x");
Node t = p.parse();
FormattingNode witness = new SimpleKeywordNode("x");
witness.setFormatInfo(new FormatInfo(4, 5, false, true));
Assertions.assertEquals(witness, t);
}
{
Parser<Object> p = new Parser<>("%-4.-5x");
Node t = p.parse();
FormattingNode witness = new SimpleKeywordNode("x");
witness.setFormatInfo(new FormatInfo(4, 5, false, false));
Assertions.assertEquals(witness, t);
}
{
Parser<Object> p = new Parser<>("%-4.5x %12y");
Node t = p.parse();
FormattingNode witness = new SimpleKeywordNode("x");
witness.setFormatInfo(new FormatInfo(4, 5, false, true));
Node n = witness.next = new Node(Node.LITERAL, " ");
n = n.next = new SimpleKeywordNode("y");
((FormattingNode) n).setFormatInfo(new FormatInfo(12, Integer.MAX_VALUE));
Assertions.assertEquals(witness, t);
}
}
@Test
public void testOptions0() throws Exception {
Parser<Object> p = new Parser<>("%45x{'test '}");
Node t = p.parse();
SimpleKeywordNode witness = new SimpleKeywordNode("x");
witness.setFormatInfo(new FormatInfo(45, Integer.MAX_VALUE));
List<String> ol = new ArrayList<String>();
ol.add("test ");
witness.setOptions(ol);
Assertions.assertEquals(witness, t);
}
@Test
public void testOptions1() throws Exception {
Parser<Object> p = new Parser<>("%45x{a, b}");
Node t = p.parse();
SimpleKeywordNode witness = new SimpleKeywordNode("x");
witness.setFormatInfo(new FormatInfo(45, Integer.MAX_VALUE));
List<String> ol = new ArrayList<String>();
ol.add("a");
ol.add("b");
witness.setOptions(ol);
Assertions.assertEquals(witness, t);
}
// see http://jira.qos.ch/browse/LBCORE-180
@Test
public void keywordGluedToLitteral() throws Exception {
Parser<Object> p = new Parser<>("%x{}a");
Node t = p.parse();
SimpleKeywordNode witness = new SimpleKeywordNode("x");
witness.setOptions(new ArrayList<String>());
witness.next = new Node(Node.LITERAL, "a");
Assertions.assertEquals(witness, t);
}
@Test
public void testCompositeFormatting() throws Exception {
Parser<Object> p = new Parser<>("hello%5(XYZ)");
Node t = p.parse();
Node witness = new Node(Node.LITERAL, "hello");
CompositeNode composite = new CompositeNode(BARE);
composite.setFormatInfo(new FormatInfo(5, Integer.MAX_VALUE));
Node child = new Node(Node.LITERAL, "XYZ");
composite.setChildNode(child);
witness.next = composite;
Assertions.assertEquals(witness, t);
}
@Test
public void empty() {
try {
Parser<Object> p = new Parser<>("");
p.parse();
Assertions.fail("");
} catch (ScanException e) {
}
}
@Test
public void lbcore193() throws Exception {
try {
Parser<Object> p = new Parser<>("hello%(abc");
p.setContext(context);
p.parse();
Assertions.fail("where the is exception?");
} catch (ScanException ise) {
Assertions.assertEquals("Expecting RIGHT_PARENTHESIS token but got null", ise.getMessage());
}
StatusChecker sc = new StatusChecker(context);
sc.assertContainsMatch("Expecting RIGHT_PARENTHESIS");
sc.assertContainsMatch("See also " + Parser.MISSING_RIGHT_PARENTHESIS);
}
}