ronantakizawa/codereview-bench huggingface dataset:
Repository: uber-go/zap
File: logger.go (Go)

Code before:
	ce.ErrorOutput = log.errorOutput
	if log.addCaller {
		frame, defined := getCallerFrame(log.callerSkip + callerSkipOffset)
		if !defined {
			fmt.Fprintf(log.errorOutput, "%v Logger.check error: failed to get caller\n", time.Now().UTC())
			log.errorOutput.Sync()
		}

		ce.Entry.Caller = zapcore.EntryCaller{
			Defined:  defined,
			PC:       frame.PC,
			File:     frame.File,
			Line:     frame.Line,
			Function: frame.Function,
		}
	}
	if log.addStack.Enabled(ce.Entry.Level) {
		ce.Entry.Stack = Stack("").String
	}

	return ce
}

// getCallerFrame gets caller frame. The argument skip is the number of stack
// frames to ascend, with 0 identifying the caller of getCallerFrame. The
// boolean ok is false if it was not possible to recover the information.
func getCallerFrame(skip int) (frame runtime.Frame, ok bool) {
	const skipOffset = 2

	pc := make([]uintptr, 1)
	numFrames := runtime.Callers(skip+skipOffset, pc[:])
	if numFrames < 1 {
		return
	}

	frame, _ = runtime.CallersFrames(pc).Next()
	return frame, frame.PC != 0
}


Review comment (suggestion):
```suggestion
// boolean ok is false if it was not possible to recover the information.
//
// Note: This implementation is similar to runtime.Caller, but it returns the whole frame.
```

Code after:
	ce.ErrorOutput = log.errorOutput
	if log.addCaller {
		frame, defined := getCallerFrame(log.callerSkip + callerSkipOffset)
		if !defined {
			fmt.Fprintf(log.errorOutput, "%v Logger.check error: failed to get caller\n", time.Now().UTC())
			log.errorOutput.Sync()
		}

		ce.Entry.Caller = zapcore.EntryCaller{
			Defined:  defined,
			PC:       frame.PC,
			File:     frame.File,
			Line:     frame.Line,
			Function: frame.Function,
		}
	}
	if log.addStack.Enabled(ce.Entry.Level) {
		ce.Entry.Stack = Stack("").String
	}

	return ce
}

// getCallerFrame gets caller frame. The argument skip is the number of stack
// frames to ascend, with 0 identifying the caller of getCallerFrame. The
// boolean ok is false if it was not possible to recover the information.
//
// Note: This implementation is similar to runtime.Caller, but it returns the whole frame.
func getCallerFrame(skip int) (frame runtime.Frame, ok bool) {
	const skipOffset = 2 // skip getCallerFrame and Callers

	pc := make([]uintptr, 1)
	numFrames := runtime.Callers(skip+skipOffset, pc[:])
	if numFrames < 1 {
		return
	}

	frame, _ = runtime.CallersFrames(pc).Next()
	return frame, frame.PC != 0
}
Repository: uber-go/zap
File: logger.go (Go)

Code before:
			fmt.Fprintf(log.errorOutput, "%v Logger.check error: failed to get caller\n", time.Now().UTC())
			log.errorOutput.Sync()
		}

		ce.Entry.Caller = zapcore.EntryCaller{
			Defined:  defined,
			PC:       frame.PC,
			File:     frame.File,
			Line:     frame.Line,
			Function: frame.Function,
		}
	}
	if log.addStack.Enabled(ce.Entry.Level) {
		ce.Entry.Stack = Stack("").String
	}

	return ce
}

// getCallerFrame gets caller frame. The argument skip is the number of stack
// frames to ascend, with 0 identifying the caller of getCallerFrame. The
// boolean ok is false if it was not possible to recover the information.
//
// Note: This implementation is similar to runtime.Caller, but it returns the whole frame.
func getCallerFrame(skip int) (frame runtime.Frame, ok bool) {
	const skipOffset = 2

	pc := make([]uintptr, 1)
	numFrames := runtime.Callers(skip+skipOffset, pc[:])
	if numFrames < 1 {
		return
	}

	frame, _ = runtime.CallersFrames(pc).Next()
	return frame, frame.PC != 0
}


Review comment (suggestion):
It would help here to add a comment explaining which two frames are being skipped with this offset.

```suggestion
	const skipOffset = 2 // skip getCallerFrame and Callers
```

Code after:
			fmt.Fprintf(log.errorOutput, "%v Logger.check error: failed to get caller\n", time.Now().UTC())
			log.errorOutput.Sync()
		}

		ce.Entry.Caller = zapcore.EntryCaller{
			Defined:  defined,
			PC:       frame.PC,
			File:     frame.File,
			Line:     frame.Line,
			Function: frame.Function,
		}
	}
	if log.addStack.Enabled(ce.Entry.Level) {
		ce.Entry.Stack = Stack("").String
	}

	return ce
}

// getCallerFrame gets caller frame. The argument skip is the number of stack
// frames to ascend, with 0 identifying the caller of getCallerFrame. The
// boolean ok is false if it was not possible to recover the information.
//
// Note: This implementation is similar to runtime.Caller, but it returns the whole frame.
func getCallerFrame(skip int) (frame runtime.Frame, ok bool) {
	const skipOffset = 2 // skip getCallerFrame and Callers

	pc := make([]uintptr, 1)
	numFrames := runtime.Callers(skip+skipOffset, pc[:])
	if numFrames < 1 {
		return
	}

	frame, _ = runtime.CallersFrames(pc).Next()
	return frame, frame.PC != 0
}
Repository: uber-go/zap
File: zapcore/field.go (Go)

Code before:
		return false
	}
	if f.Key != other.Key {
		return false
	}

	switch f.Type {
	case BinaryType, ByteStringType:
		return bytes.Equal(f.Interface.([]byte), other.Interface.([]byte))
	case ArrayMarshalerType, ObjectMarshalerType, ErrorType, ReflectType:
		return reflect.DeepEqual(f.Interface, other.Interface)
	default:
		return f == other
	}
}

func addFields(enc ObjectEncoder, fields []Field) {
	for i := range fields {
		fields[i].AddTo(enc)
	}
}

func encodeStringer(key string, stringer interface{}, enc ObjectEncoder) (err error) {
	defer func() {
		if v := recover(); v != nil {
			err = fmt.Errorf("PANIC=%v", v)
		}
	}()

	enc.AddString(key, stringer.(fmt.Stringer).String())
	return
}


Review comment (suggestion):
```suggestion
			// See also https://golang.org/src/fmt/print.go#L540.
			val := reflect.ValueOf(stringer)
```

Code after:
		return false
	}
	if f.Key != other.Key {
		return false
	}

	switch f.Type {
	case BinaryType, ByteStringType:
		return bytes.Equal(f.Interface.([]byte), other.Interface.([]byte))
	case ArrayMarshalerType, ObjectMarshalerType, ErrorType, ReflectType:
		return reflect.DeepEqual(f.Interface, other.Interface)
	default:
		return f == other
	}
}

func addFields(enc ObjectEncoder, fields []Field) {
	for i := range fields {
		fields[i].AddTo(enc)
	}
}

func encodeStringer(key string, stringer interface{}, enc ObjectEncoder) (err error) {
	defer func() {
		if v := recover(); v != nil {
			val := reflect.ValueOf(stringer)
			if val.Kind() == reflect.Ptr && val.IsNil() {
				enc.AddString(key, "<nil>")
			} else {
				err = fmt.Errorf("PANIC=%v", v)
			}
		}
	}()

	enc.AddString(key, stringer.(fmt.Stringer).String())
	return
}
Repository: uber-go/zap
File: zapcore/field.go (Go)

Code before:
		return reflect.DeepEqual(f.Interface, other.Interface)
	default:
		return f == other
	}
}

func addFields(enc ObjectEncoder, fields []Field) {
	for i := range fields {
		fields[i].AddTo(enc)
	}
}

func encodeStringer(key string, stringer interface{}, enc ObjectEncoder) (retErr error) {
	// Try to capture panics (from nil references or otherwise) when calling
	// the String() method, similar to https://golang.org/src/fmt/print.go#L540
	defer func() {
		if rerr := recover(); rerr != nil {
			// If it's a nil pointer, just say "<nil>". The likeliest causes are a
			// Stringer that fails to guard against nil or a nil pointer for a
			// value receiver, and in either case, "<nil>" is a nice result.
			if v := reflect.ValueOf(stringer); v.Kind() == reflect.Ptr && v.IsNil() {
				enc.AddString(key, "<nil>")
				return
			}

			retErr = fmt.Errorf("PANIC=%v", rerr)
		}
	}()

	enc.AddString(key, stringer.(fmt.Stringer).String())
	return nil
}


Review comment (suggestion):
```suggestion
			retErr = fmt.Errorf("PANIC=%v", err)
```

Code after:
		return reflect.DeepEqual(f.Interface, other.Interface)
	default:
		return f == other
	}
}

func addFields(enc ObjectEncoder, fields []Field) {
	for i := range fields {
		fields[i].AddTo(enc)
	}
}

func encodeStringer(key string, stringer interface{}, enc ObjectEncoder) (retErr error) {
	// Try to capture panics (from nil references or otherwise) when calling
	// the String() method, similar to https://golang.org/src/fmt/print.go#L540
	defer func() {
		if err := recover(); err != nil {
			// If it's a nil pointer, just say "<nil>". The likeliest causes are a
			// Stringer that fails to guard against nil or a nil pointer for a
			// value receiver, and in either case, "<nil>" is a nice result.
			if v := reflect.ValueOf(stringer); v.Kind() == reflect.Ptr && v.IsNil() {
				enc.AddString(key, "<nil>")
				return
			}

			retErr = fmt.Errorf("PANIC=%v", err)
		}
	}()

	enc.AddString(key, stringer.(fmt.Stringer).String())
	return nil
}
Repository: uber-go/zap
File: clock.go (Go)

Code before:
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package zap

import "time"

// Clock represents time source.
type Clock interface {
	// Now returns current time.
	Now() time.Time
}

// systemClock implements default Clock that uses system time.
type systemClock struct{}

func (systemClock) Now() time.Time {
	return time.Now()
}


Review comment (suggestion):
Converting a `struct` to an `interface` costs an allocation.
We can front-load this allocation once by declaring an unexported systemClock
instance with the Clock type and using that instead.

```suggestion
// systemClock implements default Clock that uses system time.
type systemClock struct{}

var _systemClock Clock = systemClock{}

func (systemClock) Now() time.Time {
	return time.Now()
}
```

Code after:
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package zap

import "time"

// Clock is a source of time for logged entries.
type Clock interface {
	// Now returns the current local time.
	Now() time.Time
}

// systemClock implements default Clock that uses system time.
type systemClock struct{}

var _systemClock Clock = systemClock{}

func (systemClock) Now() time.Time {
	return time.Now()
}
Repository: uber-go/zap
File: clock.go (Go)

Code before:
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package zap

import "time"

// Clock represents time source.
type Clock interface {
	// Now returns current time.
	Now() time.Time
}

// systemClock implements default Clock that uses system time.
type systemClock struct{}

func (systemClock) Now() time.Time {
	return time.Now()
}


Review comment (suggestion):
```suggestion
// Clock is a source of time for logged entries.
type Clock interface {
	// Now returns the current local time.
```

Code after:
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package zap

import "time"

// Clock is a source of time for logged entries.
type Clock interface {
	// Now returns the current local time.
	Now() time.Time
}

// systemClock implements default Clock that uses system time.
type systemClock struct{}

var _systemClock Clock = systemClock{}

func (systemClock) Now() time.Time {
	return time.Now()
}
Repository: uber-go/zap
File: options.go (Go)

Code before:
	return optionFunc(func(log *Logger) {
		log.addStack = lvl
	})
}

// IncreaseLevel increase the level of the logger. It has no effect if
// the passed in level tries to decrease the level of the logger.
func IncreaseLevel(lvl zapcore.LevelEnabler) Option {
	return optionFunc(func(log *Logger) {
		core, err := zapcore.NewIncreaseLevelCore(log.core, lvl)
		if err != nil {
			fmt.Fprintf(log.errorOutput, "failed to IncreaseLevel: %v\n", err)
		} else {
			log.core = core
		}
	})
}

// OnFatal sets the action to take on fatal logs.
func OnFatal(action zapcore.CheckWriteAction) Option {
	return optionFunc(func(log *Logger) {
		log.onFatal = action
	})
}

// WithClock configures the Logger to use Clock while creating entries.
func WithClock(clock Clock) Option {
	return optionFunc(func(log *Logger) {
		log.clock = clock
	})
}


Review comment (suggestion):
```suggestion
// WithClock specifies the clock used by the logger to determine the current
// time for logged entries. Defaults to the system clock with time.Now.
```

Code after:
	return optionFunc(func(log *Logger) {
		log.addStack = lvl
	})
}

// IncreaseLevel increase the level of the logger. It has no effect if
// the passed in level tries to decrease the level of the logger.
func IncreaseLevel(lvl zapcore.LevelEnabler) Option {
	return optionFunc(func(log *Logger) {
		core, err := zapcore.NewIncreaseLevelCore(log.core, lvl)
		if err != nil {
			fmt.Fprintf(log.errorOutput, "failed to IncreaseLevel: %v\n", err)
		} else {
			log.core = core
		}
	})
}

// OnFatal sets the action to take on fatal logs.
func OnFatal(action zapcore.CheckWriteAction) Option {
	return optionFunc(func(log *Logger) {
		log.onFatal = action
	})
}

// WithClock specifies the clock used by the logger to determine the current
// time for logged entries. Defaults to the system clock with time.Now.
func WithClock(clock Clock) Option {
	return optionFunc(func(log *Logger) {
		log.clock = clock
	})
}
Repository: uber-go/zap
File: clock_test.go (Go)

Code before:
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package zap

import (
	"testing"
	"time"

	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
	"go.uber.org/zap/zaptest/observer"
)

type constantClock struct {
	now time.Time
}

func (c constantClock) Now() time.Time { return c.now }

func TestWithClock(t *testing.T) {
	date := time.Date(2077, 1, 23, 10, 15, 13, 441, time.UTC)
	clock := constantClock{now: date}
	withLogger(t, DebugLevel, []Option{WithClock(clock)}, func(log *Logger, logs *observer.ObservedLogs) {
		log.Info("")
		require.Equal(t, 1, logs.Len(), "Expected only one log entry to be written.")
		assert.Equal(t, date, logs.All()[0].Entry.Time, "Unexpected entry time.")
	})
}


Review comment (refactor):
We can simplify this a bit.

```suggestion
type constantClock time.Time

func (c constantClock) Now() time.Time { return time.Time(c) }

func TestWithClock(t *testing.T) {
	date := time.Date(2077, 1, 23, 10, 15, 13, 441, time.UTC)
	clock := constantClock(date)
```

Code after:
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package zap

import (
	"testing"
	"time"

	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
	"go.uber.org/zap/zaptest/observer"
)

type constantClock time.Time

func (c constantClock) Now() time.Time { return time.Time(c) }

func TestWithClock(t *testing.T) {
	date := time.Date(2077, 1, 23, 10, 15, 13, 441, time.UTC)
	clock := constantClock(date)
	withLogger(t, DebugLevel, []Option{WithClock(clock)}, func(log *Logger, logs *observer.ObservedLogs) {
		log.Info("")
		require.Equal(t, 1, logs.Len(), "Expected only one log entry to be written.")
		assert.Equal(t, date, logs.All()[0].Entry.Time, "Unexpected entry time.")
	})
}
Repository: uber-go/zap
File: http_handler.go (Go)

Code before:

	case http.MethodGet:
		current := lvl.Level()
		enc.Encode(payload{Level: &current})

	case http.MethodPut:
		requestedLvl, err := func(body io.Reader) (*zapcore.Level, error) {
			switch r.Header.Get("Content-Type") {
			case "application/x-www-form-urlencoded":
				pld, err := ioutil.ReadAll(body)
				if err != nil {
					return nil, err
				}
				values, err := url.ParseQuery(string(pld))
				if err != nil {
					return nil, err
				}
				lvl := values.Get("level")
				if lvl == "" {
					return nil, fmt.Errorf("must specify logging level")
				}
				var l zapcore.Level
				if err := l.UnmarshalText([]byte(lvl)); err != nil {
					return nil, err
				}
				return &l, nil
			default:
				var pld payload
				if err := json.NewDecoder(r.Body).Decode(&pld); err != nil {
					return nil, fmt.Errorf("malformed request body: %v", err)
				}
				if pld.Level == nil {
					return nil, fmt.Errorf("must specify logging level")
				}
				return pld.Level, nil
			}
		}(r.Body)
		if err != nil {
			w.WriteHeader(http.StatusBadRequest)
			enc.Encode(errorResponse{Error: err.Error()})
			return
		}
		lvl.SetLevel(*requestedLvl)
		enc.Encode(payload{Level: requestedLvl})
	default:
		w.WriteHeader(http.StatusMethodNotAllowed)
		enc.Encode(errorResponse{
			Error: "Only GET and PUT are supported.",
		})
	}
}

Review comment (suggestion):
Optionally, this can be shortened.
```suggestion
				err := l.UnmarshalText([]byte(lvl))
				return &l, err
```

Code after:
	enc := json.NewEncoder(w)

	switch r.Method {
	case http.MethodGet:
		enc.Encode(payload{Level: lvl.Level()})
	case http.MethodPut:
		requestedLvl, err := decodePutRequest(r.Header.Get("Content-Type"), r)
		if err != nil {
			w.WriteHeader(http.StatusBadRequest)
			enc.Encode(errorResponse{Error: err.Error()})
			return
		}
		lvl.SetLevel(requestedLvl)
		enc.Encode(payload{Level: lvl.Level()})
	default:
		w.WriteHeader(http.StatusMethodNotAllowed)
		enc.Encode(errorResponse{
			Error: "Only GET and PUT are supported.",
		})
	}
}

// Decodes incoming PUT requests and returns the requested logging level.
func decodePutRequest(contentType string, r *http.Request) (zapcore.Level, error) {
	if contentType == "application/x-www-form-urlencoded" {
		return decodePutURL(r)
	}
	return decodePutJSON(r.Body)
}

func decodePutURL(r *http.Request) (zapcore.Level, error) {
	lvl := r.FormValue("level")
	if lvl == "" {
		return 0, fmt.Errorf("must specify logging level")
	}
	var l zapcore.Level
	if err := l.UnmarshalText([]byte(lvl)); err != nil {
		return 0, err
	}
	return l, nil
}

func decodePutJSON(body io.Reader) (zapcore.Level, error) {
	var pld struct {
		Level *zapcore.Level `json:"level"`
	}
	if err := json.NewDecoder(body).Decode(&pld); err != nil {
		return 0, fmt.Errorf("malformed request body: %v", err)
	}
	if pld.Level == nil {
		return 0, fmt.Errorf("must specify logging level")
Repository: uber-go/zap
File: http_handler_test.go (Go)

Code before:
// THE SOFTWARE.

package zap_test

import (
	"encoding/json"
	"net/http"
	"net/http/httptest"
	"strings"
	"testing"

	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"

	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
)

func TestAtomicLevelServeHTTP(t *testing.T) {
	tests := map[string]struct {
		Method        string
		ContentType   string
		Body          string
		ExpectedCode  int
		ExpectedLevel zapcore.Level
	}{
		"GET": {
			Method:        http.MethodGet,
			ExpectedCode:  http.StatusOK,
			ExpectedLevel: zap.InfoLevel,
		},
		"PUT JSON": {
			Method:        http.MethodPut,
			ExpectedCode:  http.StatusOK,
			ExpectedLevel: zap.WarnLevel,
			Body:          `{"level":"warn"}`,
		},
		"PUT URL encoded": {
			Method:        http.MethodPut,
			ExpectedCode:  http.StatusOK,
			ExpectedLevel: zap.WarnLevel,
			ContentType:   "application/x-www-form-urlencoded",
			Body:          "level=warn",
		},
		"PUT JSON unrecognized": {
			Method:       http.MethodPut,
			ExpectedCode: http.StatusBadRequest,
			Body:         `{"level":"unrecognized"}`,
		},
		"PUT URL encoded unrecognized": {
			Method:       http.MethodPut,

Review comment (suggestion):
Thanks for making this a table test. If you wouldn't mind, we have a preference for slice-based table tests rather than maps:

```
tests :=  []struct {
  desc string
  method string
  contentType string
  ...
}{
  ...
}

for _, tt := range tests {
  ..
```

(See also https://github.com/uber-go/guide/blob/master/style.md#test-tables)

Code after:
// THE SOFTWARE.

package zap_test

import (
	"encoding/json"
	"net/http"
	"net/http/httptest"
	"strings"
	"testing"

	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"

	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
)

func TestAtomicLevelServeHTTP(t *testing.T) {
	tests := []struct {
		desc          string
		method        string
		query         string
		contentType   string
		body          string
		expectedCode  int
		expectedLevel zapcore.Level
	}{
		{
			desc:          "GET",
			method:        http.MethodGet,
			expectedCode:  http.StatusOK,
			expectedLevel: zap.InfoLevel,
		},
		{
			desc:          "PUT JSON",
			method:        http.MethodPut,
			expectedCode:  http.StatusOK,
			expectedLevel: zap.WarnLevel,
			body:          `{"level":"warn"}`,
		},
		{
			desc:          "PUT URL encoded",
			method:        http.MethodPut,
			expectedCode:  http.StatusOK,
			expectedLevel: zap.WarnLevel,
			contentType:   "application/x-www-form-urlencoded",
			body:          "level=warn",
		},
		{
			desc:          "PUT query parameters",