ConverterUtilTest.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;

import java.util.HashMap;
import java.util.Map;
import java.util.function.Supplier;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import ch.qos.logback.core.Context;
import ch.qos.logback.core.ContextBase;
import ch.qos.logback.core.pattern.parser.Node;
import ch.qos.logback.core.pattern.parser.Parser;
import ch.qos.logback.core.spi.ContextAware;
import ch.qos.logback.core.spi.LifeCycle;
import ch.qos.logback.core.spi.ScanException;

// inspired by ch.qos.logback.core.pattern.parser.CompilerTest
public class ConverterUtilTest {

    Map<String, Supplier<DynamicConverter>> converterMap = new HashMap<>();
    Context context = new ContextBase();

    @BeforeEach
    public void setUp() {
        converterMap.put("OTT", Converter123::new);
        converterMap.put("hello", ConverterHello::new);
        converterMap.putAll(Parser.DEFAULT_COMPOSITE_CONVERTER_MAP);
    }

    @Test
    public void contextAndStartTest() throws ScanException {
        testContextAndStart("hi %hello");
        testContextAndStart("hi %(%hello)");
        testContextAndStart("hi %(abc %(%hello))");

    }

    private void testContextAndStart(String pattern) throws ScanException {
        Parser<Object> p = new Parser<Object>(pattern);
        p.setContext(context);
        Node t = p.parse();
        Converter<Object> head = p.compile(t, converterMap);
        ConverterUtil.setContextForConverters(context, head);
        checkContext(head);

        ConverterUtil.startConverters(head);
        checkStart(head);
    }

    private void checkStart(Converter<Object> head) {
        Converter<Object> c = head;
        while (c != null) {
            if (c instanceof LifeCycle) {
                LifeCycle ca = (LifeCycle) c;
                Assertions.assertTrue(ca.isStarted());
            }
            if (c instanceof CompositeConverter) {
                CompositeConverter<Object> cc = (CompositeConverter<Object>) c;
                Converter<Object> childConverter = cc.childConverter;
                checkStart(childConverter);
            }
            c = c.getNext();
        }

    }

    void checkContext(Converter<Object> head) {
        Converter<Object> c = head;
        while (c != null) {
            if (c instanceof ContextAware) {
                ContextAware ca = (ContextAware) c;
                Assertions.assertNotNull(ca.getContext());
            }
            if (c instanceof CompositeConverter) {
                CompositeConverter<Object> cc = (CompositeConverter<Object>) c;
                Converter<Object> childConverter = cc.childConverter;
                checkContext(childConverter);
            }
            c = c.getNext();
        }
    }

}