1// Copyright (c) 2012 - Cloud Instruments Co., Ltd.
2//
3// All rights reserved.
4//
5// Redistribution and use in source and binary forms, with or without
6// modification, are permitted provided that the following conditions are met:
7//
8// 1. Redistributions of source code must retain the above copyright notice, this
9//    list of conditions and the following disclaimer.
10// 2. Redistributions in binary form must reproduce the above copyright notice,
11//    this list of conditions and the following disclaimer in the documentation
12//    and/or other materials provided with the distribution.
13//
14// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
15// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
18// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24
25package seelog
26
27import (
28	"os"
29	"path/filepath"
30	"strings"
31	"testing"
32)
33
34const (
35	testShortPath = "common_context_test.go"
36)
37
38var (
39	commonPrefix string
40	testFullPath string
41)
42
43func init() {
44	// Here we remove the hardcoding of the package name which
45	// may break forks and some CI environments such as jenkins.
46	ctx, _ := extractCallerInfo(1)
47	funcName := ctx.funcName
48	preIndex := strings.Index(funcName, "init·")
49	if preIndex == -1 {
50		preIndex = strings.Index(funcName, "init")
51	}
52	commonPrefix = funcName[:preIndex]
53	wd, err := os.Getwd()
54	if err == nil {
55		// Transform the file path into a slashed form:
56		// This is the proper platform-neutral way.
57		testFullPath = filepath.ToSlash(filepath.Join(wd, testShortPath))
58	}
59}
60
61func TestContext(t *testing.T) {
62	context, err := currentContext(nil)
63	if err != nil {
64		t.Fatalf("unexpected error: %s", err)
65	}
66	if context == nil {
67		t.Fatalf("unexpected error: context is nil")
68	}
69	if fn, funcName := context.Func(), commonPrefix+"TestContext"; fn != funcName {
70		// Account for a case when the func full path is longer than commonPrefix but includes it.
71		if !strings.HasSuffix(fn, funcName) {
72			t.Errorf("expected context.Func == %s ; got %s", funcName, context.Func())
73		}
74	}
75	if context.ShortPath() != testShortPath {
76		t.Errorf("expected context.ShortPath == %s ; got %s", testShortPath, context.ShortPath())
77	}
78	if len(testFullPath) == 0 {
79		t.Fatal("working directory seems invalid")
80	}
81	if context.FullPath() != testFullPath {
82		t.Errorf("expected context.FullPath == %s ; got %s", testFullPath, context.FullPath())
83	}
84}
85
86func innerContext() (context LogContextInterface, err error) {
87	return currentContext(nil)
88}
89
90func TestInnerContext(t *testing.T) {
91	context, err := innerContext()
92	if err != nil {
93		t.Fatalf("unexpected error: %s", err)
94	}
95	if context == nil {
96		t.Fatalf("unexpected error: context is nil")
97	}
98	if fn, funcName := context.Func(), commonPrefix+"innerContext"; fn != funcName {
99		// Account for a case when the func full path is longer than commonPrefix but includes it.
100		if !strings.HasSuffix(fn, funcName) {
101			t.Errorf("expected context.Func == %s ; got %s", funcName, context.Func())
102		}
103	}
104	if context.ShortPath() != testShortPath {
105		t.Errorf("expected context.ShortPath == %s ; got %s", testShortPath, context.ShortPath())
106	}
107	if len(testFullPath) == 0 {
108		t.Fatal("working directory seems invalid")
109	}
110	if context.FullPath() != testFullPath {
111		t.Errorf("expected context.FullPath == %s ; got %s", testFullPath, context.FullPath())
112	}
113}
114
115type testContext struct {
116	field string
117}
118
119func TestCustomContext(t *testing.T) {
120	expected := "testStr"
121	context, err := currentContext(&testContext{expected})
122	if err != nil {
123		t.Fatalf("unexpected error: %s", err)
124	}
125	if st, _ := context.CustomContext().(*testContext); st.field != expected {
126		t.Errorf("expected context.CustomContext == %s ; got %s", expected, st.field)
127	}
128}
129