Repository: uber-go/zap
File: logger_test.go (Go)

Code before:
	errBuf := &ztest.Buffer{}
	withLogger(t, DebugLevel, opts(AddCaller(), ErrorOutput(errBuf)), func(log *Logger, logs *observer.ObservedLogs) {
		log.callerSkip = 1e3
		log.Info("Failure.")
		assert.Regexp(
			t,
			`Logger.check error: failed to get caller`,
			errBuf.String(),
			"Didn't find expected failure message.",
		)
		assert.Equal(
			t,
			logs.AllUntimed()[0].Entry.Message,
			"Failure.",
			"Expected original message to survive failures in runtime.Caller.")
	})
}

func TestLoggerAddFunction(t *testing.T) {
	tests := []struct {
		options []Option
		pat     string
	}{
		{opts(), `^$`},
		{opts(WithFunction(false)), `^$`},
		{opts(AddFunction()), `zap.TestLoggerAddFunction.func1$`},
		{opts(AddFunction(), WithFunction(false)), `^$`},
		{opts(WithFunction(true)), `zap.TestLoggerAddFunction.func1$`},
		{opts(WithFunction(true), WithFunction(false)), `^$`},
		{opts(AddFunction(), AddCallerSkip(1), AddCallerSkip(-1)), `zap.TestLoggerAddFunction.func1$`},
		{opts(AddFunction(), AddCallerSkip(1)), `zap.withLogger$`},
		{opts(AddFunction(), AddCallerSkip(1), AddCallerSkip(3)), `runtime.goexit$`},
	}
	for _, tt := range tests {
		withLogger(t, DebugLevel, tt.options, func(logger *Logger, logs *observer.ObservedLogs) {
			// Make sure that sugaring and desugaring resets caller skip properly.
			logger = logger.Sugar().Desugar()
			logger.Info("")
			output := logs.AllUntimed()
			assert.Equal(t, 1, len(output), "Unexpected number of logs written out.")
			assert.Regexp(
				t,
				tt.pat,
				output[0].Entry.Function,
				"Expected to find function name in output.",
			)
		})
	}
}

func TestLoggerAddFunctionFail(t *testing.T) {

Review comment (suggestion):
To avoid relying on the internal function names used when anonymous functions are used, can you put the log calls into a separate function in this file, like `func infoLog(logger *logger.Logger)` and that way, we can compare this to a value we control

Code after:
	tests := []struct {
		options         []Option
		loggerFunction  string
		sugaredFunction string
	}{
		{
			options:         opts(),
			loggerFunction:  "",
			sugaredFunction: "",
		},
		{
			options:         opts(WithCaller(false)),
			loggerFunction:  "",
			sugaredFunction: "",
		},
		{
			options:         opts(AddCaller()),
			loggerFunction:  "go.uber.org/zap.infoLog",
			sugaredFunction: "go.uber.org/zap.infoLogSugared",
		},
		{
			options:         opts(AddCaller(), WithCaller(false)),
			loggerFunction:  "",
			sugaredFunction: "",
		},
		{
			options:         opts(WithCaller(true)),
			loggerFunction:  "go.uber.org/zap.infoLog",
			sugaredFunction: "go.uber.org/zap.infoLogSugared",
		},
		{
			options:         opts(WithCaller(true), WithCaller(false)),
			loggerFunction:  "",
			sugaredFunction: "",
		},
		{
			options:         opts(AddCaller(), AddCallerSkip(1), AddCallerSkip(-1)),
			loggerFunction:  "go.uber.org/zap.infoLog",
			sugaredFunction: "go.uber.org/zap.infoLogSugared",
		},
		{
			options:         opts(AddCaller(), AddCallerSkip(2)),
			loggerFunction:  "go.uber.org/zap.withLogger",
			sugaredFunction: "go.uber.org/zap.withLogger",
		},
		{
			options:         opts(AddCaller(), AddCallerSkip(2), AddCallerSkip(3)),
			loggerFunction:  "runtime.goexit",
			sugaredFunction: "runtime.goexit",
		},
	}