package de.duehl.basics.debug;

/*
 * Copyright 2018 Christian Dühl. All rights reserved.
 *
 * This program is free software. You can redistribute it and/or
 * modify it under the same terms as perl:
 *
 * general:  http://dev.perl.org/licenses/
 * GPL:      http://dev.perl.org/licenses/gpl1.html
 * artistic: http://dev.perl.org/licenses/artistic.html
 */

import static org.junit.Assert.*;

import org.junit.Ignore;
import org.junit.Test;

import de.duehl.basics.system.OutputStreamSaveAndRelease;
import de.duehl.basics.test.OutAndErrStreamHandlingTest;
import de.duehl.basics.text.Text;

public class DebugHelperTest extends OutAndErrStreamHandlingTest {

    @Test
    public void say() {
        DebugHelper.say();
        String actual = getOutContents();
        String expected = Text.LINE_BREAK;
        assertEquals(expected, actual);
    }

    @Test
    public void sayWithText() {
        DebugHelper.say("Hello World!");
        String actual = getOutContents();
        String expected = "Hello World!" + Text.LINE_BREAK;
        assertEquals(expected, actual);
    }

    @Test
    public void sayWithoutLineBreak() {
        DebugHelper.sayWithoutLineBreak("Hello World!");
        String actual = getOutContents();
        String expected = "Hello World!";
        assertEquals(expected, actual);
    }

    @Test
    public void line() {
        DebugHelper.line();
        String actual = getOutContents();
        String expected = Text.multipleString("-", 80) + Text.LINE_BREAK;
        assertEquals(expected, actual);
    }

    @Test
    public void line10() {
        DebugHelper.line(10);
        String actual = getOutContents();
        String expected = Text.multipleString("-", 10) + Text.LINE_BREAK;
        assertEquals(expected, actual);
    }

    @Test
    public void embedTextIntoLine() {
        DebugHelper.embedTextIntoLine("foo");
        String actual = getOutContents();
        String expected = Text.multipleString("-", 37) + " foo " + Text.multipleString("-", 38)
                + Text.LINE_BREAK;
        assertEquals(expected, actual);
    }

    @Test
    public void embedTextIntoLine20() {
        DebugHelper.embedTextIntoLine("foo", 20);
        String actual = getOutContents();
        String expected = Text.multipleString("-", 7) + " foo " + Text.multipleString("-", 8)
                + Text.LINE_BREAK;
        assertEquals(expected, actual);
    }

    /*
     * Das klappt nicht über das JUnit-Testsystem, da ist der dritte Index dann leider
     * NativeMethodAccessorImpl#invoke0() ist und nicht die wirklich aufrufende Methode
     * sayWithClassAndMethod().
     */
    @Ignore
    @Test
    public void sayWithClassAndMethod() {
        String className = "DebugHelperTest";
        String methodName = "sayWithClassAndMethod";
        String message = "foo bar baz.";

        OutputStreamSaveAndRelease ossr = new OutputStreamSaveAndRelease();
        ossr.saveSystemOut();
        DebugHelper.sayWithClassAndMethod(message);
        String actual = ossr.getOutContents();
        ossr.releaseSystemOut();

        String expected = className + "#" + methodName + "(): " + methodName + "\n";

        assertEquals(expected, actual);
    }

    @Test
    public void stackTraceToString() {
        String actual = DebugHelper.stackTraceToString();
        String expected = "java.base/java.lang.Thread.getStackTrace(Thread.java:1610)\n"
                + "de.duehl.basics.debug.DebugHelper.stackTraceToString(DebugHelper.java:39)\n"
                + "de.duehl.basics.debug.DebugHelperTest.stackTraceToString(DebugHelperTest.java:108)\n"
                + "java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\n"
                + "java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)\n"
                + "java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\n"
                + "java.base/java.lang.reflect.Method.invoke(Method.java:568)\n"
                + "org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)\n"
                + "org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)\n"
                + "org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)\n"
                + "org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)\n"
                + "org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)\n"
                + "org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)\n"
                + "org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)\n"
                + "org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)\n"
                + "org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)\n"
                + "org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)\n"
                + "org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)\n"
                + "org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)\n"
                + "org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)\n"
                + "org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)\n"
                + "org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)\n"
                + "org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)\n"
                + "org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)\n"
                + "org.junit.runners.ParentRunner.run(ParentRunner.java:413)\n"
                + "org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:93)\n"
                + "org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:40)\n"
                + "org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:520)\n"
                + "org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:748)\n"
                + "org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:443)\n"
                + "org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:211)\n";
        assertEquals(expected, actual);
    }

    @Test
    public void stackTraceToStringSmall() {
        String actual = DebugHelper.stackTraceToStringSmall();
        String expected = "DebugHelperTest stackTraceToStringSmall() 145 - (DebugHelperTest.java:145)\n"
                + "NativeMethodAccessorImpl invoke0() - (NativeMethodAccessorImpl.java)\n"
                + "NativeMethodAccessorImpl invoke() 77 - (NativeMethodAccessorImpl.java:77)\n"
                + "DelegatingMethodAccessorImpl invoke() 43 - (DelegatingMethodAccessorImpl.java:43)\n"
                + "Method invoke() 568 - (Method.java:568)\n"
                + "FrameworkMethod$1 runReflectiveCall() 59 - (FrameworkMethod.java:59)\n"
                + "ReflectiveCallable run() 12 - (ReflectiveCallable.java:12)\n"
                + "FrameworkMethod invokeExplosively() 56 - (FrameworkMethod.java:56)\n"
                + "InvokeMethod evaluate() 17 - (InvokeMethod.java:17)\n"
                + "RunBefores evaluate() 26 - (RunBefores.java:26)\n"
                + "RunAfters evaluate() 27 - (RunAfters.java:27)\n"
                + "ParentRunner$3 evaluate() 306 - (ParentRunner.java:306)\n"
                + "BlockJUnit4ClassRunner$1 evaluate() 100 - (BlockJUnit4ClassRunner.java:100)\n"
                + "ParentRunner runLeaf() 366 - (ParentRunner.java:366)\n"
                + "BlockJUnit4ClassRunner runChild() 103 - (BlockJUnit4ClassRunner.java:103)\n"
                + "BlockJUnit4ClassRunner runChild() 63 - (BlockJUnit4ClassRunner.java:63)\n"
                + "ParentRunner$4 run() 331 - (ParentRunner.java:331)\n"
                + "ParentRunner$1 schedule() 79 - (ParentRunner.java:79)\n"
                + "ParentRunner runChildren() 329 - (ParentRunner.java:329)\n"
                + "ParentRunner access$100() 66 - (ParentRunner.java:66)\n"
                + "ParentRunner$2 evaluate() 293 - (ParentRunner.java:293)\n"
                + "ParentRunner$3 evaluate() 306 - (ParentRunner.java:306)\n"
                + "ParentRunner run() 413 - (ParentRunner.java:413)\n"
                + "JUnit4TestReference run() 93 - (JUnit4TestReference.java:93)\n"
                + "TestExecution run() 40 - (TestExecution.java:40)\n"
                + "RemoteTestRunner runTests() 520 - (RemoteTestRunner.java:520)\n"
                + "RemoteTestRunner runTests() 748 - (RemoteTestRunner.java:748)\n"
                + "RemoteTestRunner run() 443 - (RemoteTestRunner.java:443)\n"
                + "RemoteTestRunner main() 211 - (RemoteTestRunner.java:211)\n";
        assertEquals(expected, actual);
    }

}
