1   /*
2    * Logback: the reliable, generic, fast and flexible logging framework.
3    * Copyright (C) 1999-2026, 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 v2.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  
15  package ch.qos.logback.classic.joran.sanity;
16  
17  import ch.qos.logback.classic.LoggerContext;
18  import ch.qos.logback.classic.model.LoggerModel;
19  import ch.qos.logback.classic.model.RootLoggerModel;
20  import ch.qos.logback.core.model.AppenderModel;
21  import ch.qos.logback.core.model.Model;
22  import ch.qos.logback.core.model.conditional.IfModel;
23  import ch.qos.logback.core.status.Status;
24  import ch.qos.logback.core.status.testUtil.StatusChecker;
25  import ch.qos.logback.core.util.StatusPrinter;
26  import org.junit.jupiter.api.BeforeEach;
27  import org.junit.jupiter.api.Test;
28  
29  public class IfNestedWithinSecondPhaseElementSCTest {
30  
31      LoggerContext context = new LoggerContext();
32      IfNestedWithinSecondPhaseElementSC inwspeChecker = new IfNestedWithinSecondPhaseElementSC();
33      StatusChecker statusChecker = new StatusChecker(context);
34  
35      @BeforeEach
36      public void setUp() throws Exception {
37          inwspeChecker.setContext(context);
38      }
39  
40      @Test
41      public void smoke() {
42  
43          ClassicTopModel topModel = new ClassicTopModel();
44          inwspeChecker.check(topModel);
45          statusChecker.assertIsWarningOrErrorFree();
46      }
47  
48      @Test
49      public void singleAppender() {
50          ClassicTopModel topModel = new ClassicTopModel();
51          AppenderModel appenderModel0 = new AppenderModel();
52          appenderModel0.setLineNumber(1);
53          topModel.addSubModel(appenderModel0);
54          inwspeChecker.check(topModel);
55          statusChecker.assertIsWarningOrErrorFree();
56      }
57  
58      @Test
59      public void singleLoggerWithNestedIf() {
60          ClassicTopModel topModel = new ClassicTopModel();
61          Model rootLoggerModel = setupModel(new RootLoggerModel(), "root", 1);
62          topModel.addSubModel(rootLoggerModel);
63  
64          Model ifModel0 = setupModel(new IfModel(), "if", 2);
65          rootLoggerModel.addSubModel(ifModel0);
66  
67          Model loggerModel = setupModel(new LoggerModel(), "logger", 3);
68          topModel.addSubModel(loggerModel);
69  
70          Model ifModel1 = setupModel(new IfModel(), "if", 4);
71          loggerModel.addSubModel(ifModel1);
72  
73          Model appenderModel = setupModel(new LoggerModel(), "appender", 5);
74          topModel.addSubModel(appenderModel);
75  
76          Model ifModel2 = setupModel(new IfModel(), "if", 6);
77          appenderModel.addSubModel(ifModel2);
78  
79  
80          inwspeChecker.check(topModel);
81          StatusPrinter.print(context);
82          // Element <root> at line 1 contains a nested <if> element at line 2
83          String regex0 = "Element <root> at line 1 contains a nested <if> element at line 2";
84          statusChecker.assertContainsMatch(Status.WARN, regex0);
85  
86          String regex1 = "Element <logger> at line 3 contains a nested <if> element at line 4";
87          statusChecker.assertContainsMatch(Status.WARN, regex1);
88  
89          String regex2 = "Element <appender> at line 5 contains a nested <if> element at line 6";
90          statusChecker.assertContainsMatch(Status.WARN, regex2);
91  
92      }
93  
94  
95  
96      private Model setupModel(Model m, String tag, int line) {
97          m.setLineNumber(line);
98          m.setTag(tag);
99          return m;
100     }
101 
102 
103 }