[
  {
    "path": ".github/PULL_REQUEST_TEMPLATE.md",
    "content": "Please read the CLA carefully before submitting your contribution to Mercari.\nUnder any circumstances, by submitting your contribution, you are deemed to accept and agree to be bound by the terms and conditions of the CLA.\n\nhttps://www.mercari.com/cla/\n"
  },
  {
    "path": ".gitignore",
    "content": "httpdoc.md\ncoverage.txt"
  },
  {
    "path": "CHANGELOG.md",
    "content": "# Changelog\n\nAll notable changes to this project will be documented in this file.\n\nThe format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).\n\n## [0.2.0] - 2018-02-13\n\nIn this release, we added breaking changes by [#18](https://github.com/mercari/go-httpdoc/pull/18). Now user can set custom asset function to each test cases. Since this added new field named `AssertFunc` to `TestCase` struct, the code which uses it without specifying field name will be broken. To migrate to new version easily, we add `NewTestCase` function. Check [#18](https://github.com/mercari/go-httpdoc/pull/18) and see how our example migrate to new `TestCase` by it.\n\n### Added \n\n- Add MkdirAll if not exist output directory [#14](https://github.com/mercari/go-httpdoc/pull/14)\n\n### Changed\n\n- Allow to provide custom assert function to `TestCase` [#18](https://github.com/mercari/go-httpdoc/pull/18)\n\n### Removed\n\n- Stop support Go 1.6.x [#20](https://github.com/mercari/go-httpdoc/pull/20)\n\n\n## [0.1.0] - 2017-06-01\n\nInitial release. \n\n### Added \n\n- Fundamental features\n"
  },
  {
    "path": "LICENSE",
    "content": "Copyright (c) 2017 Mercari, Inc.\n\nMIT License\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "# go-httpdoc [![Go Documentation](http://img.shields.io/badge/go-documentation-blue.svg?style=flat-square)][godoc]\n\n[godoc]: http://godoc.org/go.mercari.io/go-httpdoc\n\n`go-httpdoc` is a Golang package to generate API documentation from [`httptest`](https://golang.org/pkg/net/http/httptest/) test cases.\n\nIt provides a simple http middleware which records http requests and responses from tests and generates documentation automatically in markdown format. See [Sample Documentation](/_example/doc/validate.md). It also provides a way to validate values are equal to what you expect with annotation (e.g., you can add a description for headers, params or response fields). If you write proper tests, it will generate usable documentation (namely, it forces you to write good tests).\n\nNot only JSON request and response but it also supports [protocol buffer](https://developers.google.com/protocol-buffers/). See [Sample ProtoBuf Documentation](/_example/doc/protobuf.md)).\n\nSee usage and example in [GoDoc](https://godoc.org/go.mercari.io/go-httpdoc).\n\n*NOTE*: This package is experimental and may make backward-incompatible changes.\n\n## Prerequisites\n\ngo-httpdoc requires Go 1.7 or later.\n\n## Install\n\nUse go get:\n\n```\n$ go get -u go.mercari.io/go-httpdoc\n```\n\n## Usage\n\nAll usage are described in [GoDoc](https://godoc.org/go.mercari.io/go-httpdoc).\n\nTo generate documentation, set the following env var:\n\n```bash\n$ export HTTPDOC=1\n```\n\n## Reference\n\nThe original idea came from [r7kamura/autodoc](https://github.com/r7kamura/autodoc) (rack middleware).\n\nFor struct inspection in validator, it uses [tenntenn/gpath](https://github.com/tenntenn/gpath) package.\n"
  },
  {
    "path": "_example/README.md",
    "content": "# httpdoc example\n\nThis directory contains some examples of `httpdoc`.\n\n- [`handler_simple_test.go`](/_example/handler_simple_test.go) generates [`doc/simple.md`](/_example/doc/simple.md)\n- [`handler_validate_test.go`](/_example/handler_validate_test.go) generates [`doc/validate.md`](/_example/doc/validate.md)\n- [`handler_proto_test.go`](/_example/handler_proto_test.go) generates [`doc/protobuf.md`](/_example/doc/protobuf.md)\n\nTo generate documentation, run the following command:\n\n```bash\n$ env HTTPDOC=1 go test -v\n```\n\nOne example uses protocol buffer, message definition is in [`../proto`](../proto) directory. To generate code from that, run the following command:\n\n```bash\n# Install protoc-gen-go if you don't have it\n$ go get -u github.com/golang/protobuf/protoc-gen-go\n\n$ protoc -I=./../proto --gofast_out=./ ../proto/message.proto\n```\n"
  },
  {
    "path": "_example/doc/protobuf.md",
    "content": "# API doc\n\nThis is API documentation for Example API (with protobuf). This is generated by `httpdoc`. Don't edit by hand.\n\n## Table of contents\n\n- [[200] GET /v2/user/169743](#200-get-v2user169743)\n\n\n## [200] GET /v2/user/169743\n\nGet a user\n\n### Request\n\n\n\n\n\n\n\n\n\n### Response\n\nHeaders\n\n| Name  | Value  | Description |\n| ----- | :----- | :--------- |\n| Content-Type | application/protobuf |  |\n\n\n\nResponse fields\n\n| Name  | Value  | Description |\n| ----- | :----- | :--------- |\n| Name | Immortan Joe | User name |\n| Setting.Email | immortan@madmax.com | User email |\n\n\n\nResponse example\n\n<details>\n<summary>Click to expand code.</summary>\n\n```javascript\n{\n  \"id\": 169743,\n  \"name\": \"Immortan Joe\",\n  \"active\": true,\n  \"setting\": {\n    \"email\": \"immortan@madmax.com\"\n  }\n}\n\n```\n\n</details>\n\n\n\n"
  },
  {
    "path": "_example/doc/simple.md",
    "content": "# API doc\n\nThis is API documentation for Example API (simple). This is generated by `httpdoc`. Don't edit by hand.\n\n## Table of contents\n\n- [[200] POST /v1/user](#200-post-v1user)\n\n\n## [200] POST /v1/user\n\nCreate a new user\n\n### Request\n\nParameters\n\n| Name  | Value  | Description |\n| ----- | :----- | :--------- |\n| token | 12345 |  |\n\n\nHeaders\n\n| Name  | Value  | Description |\n| ----- | :----- | :--------- |\n| Accept-Encoding | gzip |  |\n| User-Agent | Go-http-client/1.1 |  |\n| X-Version | 2 |  |\n\n\n\n\n\nRequest example\n\n<details>\n<summary>Click to expand code.</summary>\n\n```javascript\n{\n \"name\": \"tcnksm\",\n \"email\": \"tcnksm@mercari.com\",\n \"attribute\": {\n  \"birthday\": \"1988-11-24\"\n }\n}\n\n```\n\n</details>\n\n\n### Response\n\nHeaders\n\n| Name  | Value  | Description |\n| ----- | :----- | :--------- |\n| Content-Type | application/json |  |\n\n\n\n\n\nResponse example\n\n<details>\n<summary>Click to expand code.</summary>\n\n```javascript\n{\n \"id\": 11241988,\n \"name\": \"tcnksm\"\n}\n\n```\n\n</details>\n\n\n\n"
  },
  {
    "path": "_example/doc/validate.md",
    "content": "# API doc\n\nThis is API documentation for Example API (with validation). This is generated by `httpdoc`. Don't edit by hand.\n\n## Table of contents\n\n- [[200] POST /v1/user](#200-post-v1user)\n\n\n## [200] POST /v1/user\n\nCreate a new user\n\n### Request\n\nParameters\n\n| Name  | Value  | Description |\n| ----- | :----- | :--------- |\n| pretty |  | Pretty print response message |\n| token | 12345 | Request token |\n\n\nHeaders\n\n| Name  | Value  | Description |\n| ----- | :----- | :--------- |\n| X-Version | 2 | Request API version |\n\n\n\nRequest fields\n\n| Name  | Value  | Description |\n| ----- | :----- | :--------- |\n| Name | tcnksm | User Name |\n| Email | tcnksm@mercari.com | User email address |\n| Attribute.Birthday | 1988-11-24 | User birthday YYYY-MM-DD format |\n\n\n\nRequest example\n\n<details>\n<summary>Click to expand code.</summary>\n\n```javascript\n{\n \"name\": \"tcnksm\",\n \"email\": \"tcnksm@mercari.com\",\n \"attribute\": {\n  \"birthday\": \"1988-11-24\"\n }\n}\n\n```\n\n</details>\n\n\n### Response\n\nHeaders\n\n| Name  | Value  | Description |\n| ----- | :----- | :--------- |\n| Content-Type | application/json |  |\n\n\n\nResponse fields\n\n| Name  | Value  | Description |\n| ----- | :----- | :--------- |\n| ID | 11241988 | User ID assigned |\n\n\n\nResponse example\n\n<details>\n<summary>Click to expand code.</summary>\n\n```javascript\n{\n \"id\": 11241988,\n \"name\": \"tcnksm\"\n}\n\n```\n\n</details>\n\n\n\n"
  },
  {
    "path": "_example/handler.go",
    "content": "package main\n\nimport (\n\t\"encoding/json\"\n\t\"net/http\"\n)\n\ntype createUserRequest struct {\n\tName      string    `json:\"name\"`\n\tEmail     string    `json:\"email\"`\n\tAttribute attribute `json:\"attribute\"`\n}\n\ntype attribute struct {\n\tBirthday string `json:\"birthday,omitempty\"`\n\tGender   string `json:\"gender,omitempty\"`\n}\n\ntype createUserResponse struct {\n\tID   int    `json:\"id\"`\n\tName string `json:\"name\"`\n}\n\ntype userHandler struct {\n}\n\ntype userProtoHandler struct {\n}\n\nfunc (h *userHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {\n\tif r.Method != \"POST\" {\n\t\tw.WriteHeader(http.StatusMethodNotAllowed)\n\t\treturn\n\t}\n\n\tif v := r.URL.Query().Get(\"token\"); v != \"12345\" {\n\t\tw.WriteHeader(http.StatusUnauthorized)\n\t\treturn\n\t}\n\n\tvar request createUserRequest\n\tdecoder := json.NewDecoder(r.Body)\n\tif err := decoder.Decode(&request); err != nil {\n\t\tw.WriteHeader(http.StatusInternalServerError)\n\t\treturn\n\t}\n\n\t// Some process...\n\n\tresponse := createUserResponse{\n\t\tID:   11241988,\n\t\tName: request.Name,\n\t}\n\n\tw.WriteHeader(http.StatusOK)\n\tw.Header().Set(\"Content-Type\", \"application/json\")\n\n\tencoder := json.NewEncoder(w)\n\tencoder.SetIndent(\"\", \" \")\n\tencoder.Encode(&response)\n}\n\nfunc (h *userProtoHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {\n\tif r.Method != \"GET\" {\n\t\tw.WriteHeader(http.StatusMethodNotAllowed)\n\t\treturn\n\t}\n\n\tresponse := &UserProtoResponse{\n\t\tId:     169743,\n\t\tName:   \"Immortan Joe\",\n\t\tActive: true,\n\t\tSetting: &UserProtoResponse_Setting{\n\t\t\tEmail: \"immortan@madmax.com\",\n\t\t},\n\t}\n\tbuf, err := response.Marshal()\n\tif err != nil {\n\t\tw.WriteHeader(http.StatusInternalServerError)\n\t\treturn\n\t}\n\n\tw.WriteHeader(http.StatusOK)\n\tw.Header().Set(\"Content-Type\", \"application/protobuf\")\n\tw.Write(buf)\n}\n"
  },
  {
    "path": "_example/handler_proto_test.go",
    "content": "package main\n\nimport (\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"testing\"\n\n\thttpdoc \"go.mercari.io/go-httpdoc\"\n)\n\nfunc TestUserHandlerWithProtobuf(t *testing.T) {\n\tdocument := &httpdoc.Document{\n\t\tName: \"Example API (with protobuf)\",\n\t\tExcludeHeaders: []string{\n\t\t\t\"Accept-Encoding\",\n\t\t},\n\t}\n\tdefer func() {\n\t\tif err := document.Generate(\"doc/protobuf.md\"); err != nil {\n\t\t\tt.Fatalf(\"err: %s\", err)\n\t\t}\n\t}()\n\n\tmux := http.NewServeMux()\n\tmux.Handle(\"/v2/user/\", httpdoc.Record(&userProtoHandler{}, document, &httpdoc.RecordOption{\n\t\tDescription: \"Get a user\",\n\t\tExcludeHeaders: []string{\n\t\t\t\"User-Agent\",\n\t\t\t\"Content-Length\",\n\t\t},\n\n\t\tWithValidate: func(validator *httpdoc.Validator) {\n\t\t\tvalidator.ResponseBody(t, []httpdoc.TestCase{\n\t\t\t\thttpdoc.NewTestCase(\"Name\", \"Immortan Joe\", \"User name\"),\n\t\t\t\thttpdoc.NewTestCase(\"Setting.Email\", \"immortan@madmax.com\", \"User email\")},\n\t\t\t\t&UserProtoResponse{},\n\t\t\t)\n\t\t},\n\n\t\tWithProtoBuffer: &httpdoc.ProtoBufferOption{\n\t\t\tResponseUnmarshaler: &UserProtoResponse{},\n\t\t},\n\t}))\n\n\ttestServer := httptest.NewServer(mux)\n\tdefer testServer.Close()\n\n\treq, err := http.NewRequest(\"GET\", testServer.URL+\"/v2/user/169743\", nil)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\n\tif _, err := http.DefaultClient.Do(req); err != nil {\n\t\tt.Fatal(err)\n\t}\n}\n"
  },
  {
    "path": "_example/handler_simple_test.go",
    "content": "package main\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"testing\"\n\n\thttpdoc \"go.mercari.io/go-httpdoc\"\n)\n\nfunc TestUserHandlerSimple(t *testing.T) {\n\tdocument := &httpdoc.Document{\n\t\tName:           \"Example API (simple)\",\n\t\tExcludeHeaders: []string{\"Content-Length\"},\n\t}\n\tdefer func() {\n\t\tif err := document.Generate(\"doc/simple.md\"); err != nil {\n\t\t\tt.Fatalf(\"err: %s\", err)\n\t\t}\n\t}()\n\n\tmux := http.NewServeMux()\n\tmux.Handle(\"/v1/user\", httpdoc.Record(&userHandler{}, document, &httpdoc.RecordOption{\n\t\tDescription: \"Create a new user\",\n\t}))\n\n\ttestServer := httptest.NewServer(mux)\n\tdefer testServer.Close()\n\n\treq := testNewRequest(t, testServer.URL+\"/v1/user?token=12345\")\n\tif _, err := http.DefaultClient.Do(req); err != nil {\n\t\tt.Fatalf(\"err: %s\", err)\n\t}\n}\n\nfunc testNewRequest(t *testing.T, urlStr string) *http.Request {\n\tvar buf bytes.Buffer\n\tencoder := json.NewEncoder(&buf)\n\tencoder.SetIndent(\"\", \" \")\n\tencoder.Encode(&createUserRequest{\n\t\tName:  \"tcnksm\",\n\t\tEmail: \"tcnksm@mercari.com\",\n\t\tAttribute: attribute{\n\t\t\tBirthday: \"1988-11-24\",\n\t\t},\n\t})\n\n\treq, err := http.NewRequest(\"POST\", urlStr, &buf)\n\tif err != nil {\n\t\tt.Fatalf(\"err: %s\", err)\n\t}\n\treq.Header.Add(\"X-Version\", \"2\")\n\treturn req\n}\n"
  },
  {
    "path": "_example/handler_validate_test.go",
    "content": "package main\n\nimport (\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"testing\"\n\n\thttpdoc \"go.mercari.io/go-httpdoc\"\n)\n\nfunc TestUserHandlerWithValidate(t *testing.T) {\n\tdocument := &httpdoc.Document{\n\t\tName: \"Example API (with validation)\",\n\t\tExcludeHeaders: []string{\n\t\t\t\"Accept-Encoding\",\n\t\t},\n\t}\n\tdefer func() {\n\t\tif err := document.Generate(\"doc/validate.md\"); err != nil {\n\t\t\tt.Fatalf(\"err: %s\", err)\n\t\t}\n\t}()\n\n\tmux := http.NewServeMux()\n\tmux.Handle(\"/v1/user\", httpdoc.Record(&userHandler{}, document, &httpdoc.RecordOption{\n\t\tDescription: \"Create a new user\",\n\t\tExcludeHeaders: []string{\n\t\t\t\"User-Agent\",\n\t\t\t\"Content-Length\",\n\t\t},\n\n\t\t// WithValidate option, you can validate various http request & parameter values.\n\t\t// It checks handler gets the expected value or not and assert when it's different.\n\t\t// You can annotate what kind of value you expect (description) in each validation\n\t\t// and it will be the document.\n\t\tWithValidate: func(validator *httpdoc.Validator) {\n\t\t\tvalidator.RequestParams(t, []httpdoc.TestCase{\n\t\t\t\thttpdoc.NewTestCase(\"token\", \"12345\", \"Request token\"),\n\t\t\t\thttpdoc.NewTestCase(\"pretty\", \"\", \"Pretty print response message\"),\n\t\t\t})\n\n\t\t\tvalidator.RequestHeaders(t, []httpdoc.TestCase{\n\t\t\t\thttpdoc.NewTestCase(\"X-Version\", \"2\", \"Request API version\"),\n\t\t\t})\n\n\t\t\tvalidator.RequestBody(t, []httpdoc.TestCase{\n\t\t\t\thttpdoc.NewTestCase(\"Name\", \"tcnksm\", \"User Name\"),\n\t\t\t\thttpdoc.NewTestCase(\"Email\", \"tcnksm@mercari.com\", \"User email address\"),\n\t\t\t\thttpdoc.NewTestCase(\"Attribute.Birthday\", \"1988-11-24\", \"User birthday YYYY-MM-DD format\")},\n\t\t\t\t&createUserRequest{},\n\t\t\t)\n\n\t\t\tvalidator.ResponseStatusCode(t, http.StatusOK)\n\n\t\t\tvalidator.ResponseBody(t, []httpdoc.TestCase{\n\t\t\t\thttpdoc.NewTestCase(\"ID\", 11241988, \"User ID assigned\")},\n\t\t\t\t&createUserResponse{},\n\t\t\t)\n\t\t},\n\t}))\n\n\ttestServer := httptest.NewServer(mux)\n\tdefer testServer.Close()\n\n\treq := testNewRequest(t, testServer.URL+\"/v1/user?token=12345\")\n\tif _, err := http.DefaultClient.Do(req); err != nil {\n\t\tt.Fatalf(\"err: %s\", err)\n\t}\n}\n"
  },
  {
    "path": "_example/message.pb.go",
    "content": "// Code generated by protoc-gen-gogo.\n// source: message.proto\n// DO NOT EDIT!\n\n/*\n\tPackage httpdoc is a generated protocol buffer package.\n\n\tIt is generated from these files:\n\t\tmessage.proto\n\n\tIt has these top-level messages:\n\t\tUserProtoRequest\n\t\tUserProtoResponse\n*/\npackage main\n\nimport proto \"github.com/golang/protobuf/proto\"\nimport fmt \"fmt\"\nimport math \"math\"\n\nimport io \"io\"\n\n// Reference imports to suppress errors if they are not otherwise used.\nvar _ = proto.Marshal\nvar _ = fmt.Errorf\nvar _ = math.Inf\n\n// This is a compile-time assertion to ensure that this generated file\n// is compatible with the proto package it is being compiled against.\n// A compilation error at this line likely means your copy of the\n// proto package needs to be updated.\nconst _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package\n\ntype UserProtoRequest struct {\n\tId   int32  `protobuf:\"varint,1,opt,name=id,proto3\" json:\"id,omitempty\"`\n\tName string `protobuf:\"bytes,2,opt,name=name,proto3\" json:\"name,omitempty\"`\n}\n\nfunc (m *UserProtoRequest) Reset()                    { *m = UserProtoRequest{} }\nfunc (m *UserProtoRequest) String() string            { return proto.CompactTextString(m) }\nfunc (*UserProtoRequest) ProtoMessage()               {}\nfunc (*UserProtoRequest) Descriptor() ([]byte, []int) { return fileDescriptorMessage, []int{0} }\n\nfunc (m *UserProtoRequest) GetId() int32 {\n\tif m != nil {\n\t\treturn m.Id\n\t}\n\treturn 0\n}\n\nfunc (m *UserProtoRequest) GetName() string {\n\tif m != nil {\n\t\treturn m.Name\n\t}\n\treturn \"\"\n}\n\ntype UserProtoResponse struct {\n\tId      int32                      `protobuf:\"varint,1,opt,name=id,proto3\" json:\"id,omitempty\"`\n\tName    string                     `protobuf:\"bytes,2,opt,name=name,proto3\" json:\"name,omitempty\"`\n\tActive  bool                       `protobuf:\"varint,3,opt,name=active,proto3\" json:\"active,omitempty\"`\n\tSetting *UserProtoResponse_Setting `protobuf:\"bytes,4,opt,name=setting\" json:\"setting,omitempty\"`\n}\n\nfunc (m *UserProtoResponse) Reset()                    { *m = UserProtoResponse{} }\nfunc (m *UserProtoResponse) String() string            { return proto.CompactTextString(m) }\nfunc (*UserProtoResponse) ProtoMessage()               {}\nfunc (*UserProtoResponse) Descriptor() ([]byte, []int) { return fileDescriptorMessage, []int{1} }\n\nfunc (m *UserProtoResponse) GetId() int32 {\n\tif m != nil {\n\t\treturn m.Id\n\t}\n\treturn 0\n}\n\nfunc (m *UserProtoResponse) GetName() string {\n\tif m != nil {\n\t\treturn m.Name\n\t}\n\treturn \"\"\n}\n\nfunc (m *UserProtoResponse) GetActive() bool {\n\tif m != nil {\n\t\treturn m.Active\n\t}\n\treturn false\n}\n\nfunc (m *UserProtoResponse) GetSetting() *UserProtoResponse_Setting {\n\tif m != nil {\n\t\treturn m.Setting\n\t}\n\treturn nil\n}\n\ntype UserProtoResponse_Setting struct {\n\tEmail string `protobuf:\"bytes,1,opt,name=email,proto3\" json:\"email,omitempty\"`\n}\n\nfunc (m *UserProtoResponse_Setting) Reset()         { *m = UserProtoResponse_Setting{} }\nfunc (m *UserProtoResponse_Setting) String() string { return proto.CompactTextString(m) }\nfunc (*UserProtoResponse_Setting) ProtoMessage()    {}\nfunc (*UserProtoResponse_Setting) Descriptor() ([]byte, []int) {\n\treturn fileDescriptorMessage, []int{1, 0}\n}\n\nfunc (m *UserProtoResponse_Setting) GetEmail() string {\n\tif m != nil {\n\t\treturn m.Email\n\t}\n\treturn \"\"\n}\n\nfunc init() {\n\tproto.RegisterType((*UserProtoRequest)(nil), \"httpdoc.UserProtoRequest\")\n\tproto.RegisterType((*UserProtoResponse)(nil), \"httpdoc.UserProtoResponse\")\n\tproto.RegisterType((*UserProtoResponse_Setting)(nil), \"httpdoc.UserProtoResponse.Setting\")\n}\nfunc (m *UserProtoRequest) Marshal() (dAtA []byte, err error) {\n\tsize := m.Size()\n\tdAtA = make([]byte, size)\n\tn, err := m.MarshalTo(dAtA)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn dAtA[:n], nil\n}\n\nfunc (m *UserProtoRequest) MarshalTo(dAtA []byte) (int, error) {\n\tvar i int\n\t_ = i\n\tvar l int\n\t_ = l\n\tif m.Id != 0 {\n\t\tdAtA[i] = 0x8\n\t\ti++\n\t\ti = encodeVarintMessage(dAtA, i, uint64(m.Id))\n\t}\n\tif len(m.Name) > 0 {\n\t\tdAtA[i] = 0x12\n\t\ti++\n\t\ti = encodeVarintMessage(dAtA, i, uint64(len(m.Name)))\n\t\ti += copy(dAtA[i:], m.Name)\n\t}\n\treturn i, nil\n}\n\nfunc (m *UserProtoResponse) Marshal() (dAtA []byte, err error) {\n\tsize := m.Size()\n\tdAtA = make([]byte, size)\n\tn, err := m.MarshalTo(dAtA)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn dAtA[:n], nil\n}\n\nfunc (m *UserProtoResponse) MarshalTo(dAtA []byte) (int, error) {\n\tvar i int\n\t_ = i\n\tvar l int\n\t_ = l\n\tif m.Id != 0 {\n\t\tdAtA[i] = 0x8\n\t\ti++\n\t\ti = encodeVarintMessage(dAtA, i, uint64(m.Id))\n\t}\n\tif len(m.Name) > 0 {\n\t\tdAtA[i] = 0x12\n\t\ti++\n\t\ti = encodeVarintMessage(dAtA, i, uint64(len(m.Name)))\n\t\ti += copy(dAtA[i:], m.Name)\n\t}\n\tif m.Active {\n\t\tdAtA[i] = 0x18\n\t\ti++\n\t\tif m.Active {\n\t\t\tdAtA[i] = 1\n\t\t} else {\n\t\t\tdAtA[i] = 0\n\t\t}\n\t\ti++\n\t}\n\tif m.Setting != nil {\n\t\tdAtA[i] = 0x22\n\t\ti++\n\t\ti = encodeVarintMessage(dAtA, i, uint64(m.Setting.Size()))\n\t\tn1, err := m.Setting.MarshalTo(dAtA[i:])\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\ti += n1\n\t}\n\treturn i, nil\n}\n\nfunc (m *UserProtoResponse_Setting) Marshal() (dAtA []byte, err error) {\n\tsize := m.Size()\n\tdAtA = make([]byte, size)\n\tn, err := m.MarshalTo(dAtA)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn dAtA[:n], nil\n}\n\nfunc (m *UserProtoResponse_Setting) MarshalTo(dAtA []byte) (int, error) {\n\tvar i int\n\t_ = i\n\tvar l int\n\t_ = l\n\tif len(m.Email) > 0 {\n\t\tdAtA[i] = 0xa\n\t\ti++\n\t\ti = encodeVarintMessage(dAtA, i, uint64(len(m.Email)))\n\t\ti += copy(dAtA[i:], m.Email)\n\t}\n\treturn i, nil\n}\n\nfunc encodeFixed64Message(dAtA []byte, offset int, v uint64) int {\n\tdAtA[offset] = uint8(v)\n\tdAtA[offset+1] = uint8(v >> 8)\n\tdAtA[offset+2] = uint8(v >> 16)\n\tdAtA[offset+3] = uint8(v >> 24)\n\tdAtA[offset+4] = uint8(v >> 32)\n\tdAtA[offset+5] = uint8(v >> 40)\n\tdAtA[offset+6] = uint8(v >> 48)\n\tdAtA[offset+7] = uint8(v >> 56)\n\treturn offset + 8\n}\nfunc encodeFixed32Message(dAtA []byte, offset int, v uint32) int {\n\tdAtA[offset] = uint8(v)\n\tdAtA[offset+1] = uint8(v >> 8)\n\tdAtA[offset+2] = uint8(v >> 16)\n\tdAtA[offset+3] = uint8(v >> 24)\n\treturn offset + 4\n}\nfunc encodeVarintMessage(dAtA []byte, offset int, v uint64) int {\n\tfor v >= 1<<7 {\n\t\tdAtA[offset] = uint8(v&0x7f | 0x80)\n\t\tv >>= 7\n\t\toffset++\n\t}\n\tdAtA[offset] = uint8(v)\n\treturn offset + 1\n}\nfunc (m *UserProtoRequest) Size() (n int) {\n\tvar l int\n\t_ = l\n\tif m.Id != 0 {\n\t\tn += 1 + sovMessage(uint64(m.Id))\n\t}\n\tl = len(m.Name)\n\tif l > 0 {\n\t\tn += 1 + l + sovMessage(uint64(l))\n\t}\n\treturn n\n}\n\nfunc (m *UserProtoResponse) Size() (n int) {\n\tvar l int\n\t_ = l\n\tif m.Id != 0 {\n\t\tn += 1 + sovMessage(uint64(m.Id))\n\t}\n\tl = len(m.Name)\n\tif l > 0 {\n\t\tn += 1 + l + sovMessage(uint64(l))\n\t}\n\tif m.Active {\n\t\tn += 2\n\t}\n\tif m.Setting != nil {\n\t\tl = m.Setting.Size()\n\t\tn += 1 + l + sovMessage(uint64(l))\n\t}\n\treturn n\n}\n\nfunc (m *UserProtoResponse_Setting) Size() (n int) {\n\tvar l int\n\t_ = l\n\tl = len(m.Email)\n\tif l > 0 {\n\t\tn += 1 + l + sovMessage(uint64(l))\n\t}\n\treturn n\n}\n\nfunc sovMessage(x uint64) (n int) {\n\tfor {\n\t\tn++\n\t\tx >>= 7\n\t\tif x == 0 {\n\t\t\tbreak\n\t\t}\n\t}\n\treturn n\n}\nfunc sozMessage(x uint64) (n int) {\n\treturn sovMessage(uint64((x << 1) ^ uint64((int64(x) >> 63))))\n}\nfunc (m *UserProtoRequest) Unmarshal(dAtA []byte) error {\n\tl := len(dAtA)\n\tiNdEx := 0\n\tfor iNdEx < l {\n\t\tpreIndex := iNdEx\n\t\tvar wire uint64\n\t\tfor shift := uint(0); ; shift += 7 {\n\t\t\tif shift >= 64 {\n\t\t\t\treturn ErrIntOverflowMessage\n\t\t\t}\n\t\t\tif iNdEx >= l {\n\t\t\t\treturn io.ErrUnexpectedEOF\n\t\t\t}\n\t\t\tb := dAtA[iNdEx]\n\t\t\tiNdEx++\n\t\t\twire |= (uint64(b) & 0x7F) << shift\n\t\t\tif b < 0x80 {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tfieldNum := int32(wire >> 3)\n\t\twireType := int(wire & 0x7)\n\t\tif wireType == 4 {\n\t\t\treturn fmt.Errorf(\"proto: UserProtoRequest: wiretype end group for non-group\")\n\t\t}\n\t\tif fieldNum <= 0 {\n\t\t\treturn fmt.Errorf(\"proto: UserProtoRequest: illegal tag %d (wire type %d)\", fieldNum, wire)\n\t\t}\n\t\tswitch fieldNum {\n\t\tcase 1:\n\t\t\tif wireType != 0 {\n\t\t\t\treturn fmt.Errorf(\"proto: wrong wireType = %d for field Id\", wireType)\n\t\t\t}\n\t\t\tm.Id = 0\n\t\t\tfor shift := uint(0); ; shift += 7 {\n\t\t\t\tif shift >= 64 {\n\t\t\t\t\treturn ErrIntOverflowMessage\n\t\t\t\t}\n\t\t\t\tif iNdEx >= l {\n\t\t\t\t\treturn io.ErrUnexpectedEOF\n\t\t\t\t}\n\t\t\t\tb := dAtA[iNdEx]\n\t\t\t\tiNdEx++\n\t\t\t\tm.Id |= (int32(b) & 0x7F) << shift\n\t\t\t\tif b < 0x80 {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\tcase 2:\n\t\t\tif wireType != 2 {\n\t\t\t\treturn fmt.Errorf(\"proto: wrong wireType = %d for field Name\", wireType)\n\t\t\t}\n\t\t\tvar stringLen uint64\n\t\t\tfor shift := uint(0); ; shift += 7 {\n\t\t\t\tif shift >= 64 {\n\t\t\t\t\treturn ErrIntOverflowMessage\n\t\t\t\t}\n\t\t\t\tif iNdEx >= l {\n\t\t\t\t\treturn io.ErrUnexpectedEOF\n\t\t\t\t}\n\t\t\t\tb := dAtA[iNdEx]\n\t\t\t\tiNdEx++\n\t\t\t\tstringLen |= (uint64(b) & 0x7F) << shift\n\t\t\t\tif b < 0x80 {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tintStringLen := int(stringLen)\n\t\t\tif intStringLen < 0 {\n\t\t\t\treturn ErrInvalidLengthMessage\n\t\t\t}\n\t\t\tpostIndex := iNdEx + intStringLen\n\t\t\tif postIndex > l {\n\t\t\t\treturn io.ErrUnexpectedEOF\n\t\t\t}\n\t\t\tm.Name = string(dAtA[iNdEx:postIndex])\n\t\t\tiNdEx = postIndex\n\t\tdefault:\n\t\t\tiNdEx = preIndex\n\t\t\tskippy, err := skipMessage(dAtA[iNdEx:])\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tif skippy < 0 {\n\t\t\t\treturn ErrInvalidLengthMessage\n\t\t\t}\n\t\t\tif (iNdEx + skippy) > l {\n\t\t\t\treturn io.ErrUnexpectedEOF\n\t\t\t}\n\t\t\tiNdEx += skippy\n\t\t}\n\t}\n\n\tif iNdEx > l {\n\t\treturn io.ErrUnexpectedEOF\n\t}\n\treturn nil\n}\nfunc (m *UserProtoResponse) Unmarshal(dAtA []byte) error {\n\tl := len(dAtA)\n\tiNdEx := 0\n\tfor iNdEx < l {\n\t\tpreIndex := iNdEx\n\t\tvar wire uint64\n\t\tfor shift := uint(0); ; shift += 7 {\n\t\t\tif shift >= 64 {\n\t\t\t\treturn ErrIntOverflowMessage\n\t\t\t}\n\t\t\tif iNdEx >= l {\n\t\t\t\treturn io.ErrUnexpectedEOF\n\t\t\t}\n\t\t\tb := dAtA[iNdEx]\n\t\t\tiNdEx++\n\t\t\twire |= (uint64(b) & 0x7F) << shift\n\t\t\tif b < 0x80 {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tfieldNum := int32(wire >> 3)\n\t\twireType := int(wire & 0x7)\n\t\tif wireType == 4 {\n\t\t\treturn fmt.Errorf(\"proto: UserProtoResponse: wiretype end group for non-group\")\n\t\t}\n\t\tif fieldNum <= 0 {\n\t\t\treturn fmt.Errorf(\"proto: UserProtoResponse: illegal tag %d (wire type %d)\", fieldNum, wire)\n\t\t}\n\t\tswitch fieldNum {\n\t\tcase 1:\n\t\t\tif wireType != 0 {\n\t\t\t\treturn fmt.Errorf(\"proto: wrong wireType = %d for field Id\", wireType)\n\t\t\t}\n\t\t\tm.Id = 0\n\t\t\tfor shift := uint(0); ; shift += 7 {\n\t\t\t\tif shift >= 64 {\n\t\t\t\t\treturn ErrIntOverflowMessage\n\t\t\t\t}\n\t\t\t\tif iNdEx >= l {\n\t\t\t\t\treturn io.ErrUnexpectedEOF\n\t\t\t\t}\n\t\t\t\tb := dAtA[iNdEx]\n\t\t\t\tiNdEx++\n\t\t\t\tm.Id |= (int32(b) & 0x7F) << shift\n\t\t\t\tif b < 0x80 {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\tcase 2:\n\t\t\tif wireType != 2 {\n\t\t\t\treturn fmt.Errorf(\"proto: wrong wireType = %d for field Name\", wireType)\n\t\t\t}\n\t\t\tvar stringLen uint64\n\t\t\tfor shift := uint(0); ; shift += 7 {\n\t\t\t\tif shift >= 64 {\n\t\t\t\t\treturn ErrIntOverflowMessage\n\t\t\t\t}\n\t\t\t\tif iNdEx >= l {\n\t\t\t\t\treturn io.ErrUnexpectedEOF\n\t\t\t\t}\n\t\t\t\tb := dAtA[iNdEx]\n\t\t\t\tiNdEx++\n\t\t\t\tstringLen |= (uint64(b) & 0x7F) << shift\n\t\t\t\tif b < 0x80 {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tintStringLen := int(stringLen)\n\t\t\tif intStringLen < 0 {\n\t\t\t\treturn ErrInvalidLengthMessage\n\t\t\t}\n\t\t\tpostIndex := iNdEx + intStringLen\n\t\t\tif postIndex > l {\n\t\t\t\treturn io.ErrUnexpectedEOF\n\t\t\t}\n\t\t\tm.Name = string(dAtA[iNdEx:postIndex])\n\t\t\tiNdEx = postIndex\n\t\tcase 3:\n\t\t\tif wireType != 0 {\n\t\t\t\treturn fmt.Errorf(\"proto: wrong wireType = %d for field Active\", wireType)\n\t\t\t}\n\t\t\tvar v int\n\t\t\tfor shift := uint(0); ; shift += 7 {\n\t\t\t\tif shift >= 64 {\n\t\t\t\t\treturn ErrIntOverflowMessage\n\t\t\t\t}\n\t\t\t\tif iNdEx >= l {\n\t\t\t\t\treturn io.ErrUnexpectedEOF\n\t\t\t\t}\n\t\t\t\tb := dAtA[iNdEx]\n\t\t\t\tiNdEx++\n\t\t\t\tv |= (int(b) & 0x7F) << shift\n\t\t\t\tif b < 0x80 {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tm.Active = bool(v != 0)\n\t\tcase 4:\n\t\t\tif wireType != 2 {\n\t\t\t\treturn fmt.Errorf(\"proto: wrong wireType = %d for field Setting\", wireType)\n\t\t\t}\n\t\t\tvar msglen int\n\t\t\tfor shift := uint(0); ; shift += 7 {\n\t\t\t\tif shift >= 64 {\n\t\t\t\t\treturn ErrIntOverflowMessage\n\t\t\t\t}\n\t\t\t\tif iNdEx >= l {\n\t\t\t\t\treturn io.ErrUnexpectedEOF\n\t\t\t\t}\n\t\t\t\tb := dAtA[iNdEx]\n\t\t\t\tiNdEx++\n\t\t\t\tmsglen |= (int(b) & 0x7F) << shift\n\t\t\t\tif b < 0x80 {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tif msglen < 0 {\n\t\t\t\treturn ErrInvalidLengthMessage\n\t\t\t}\n\t\t\tpostIndex := iNdEx + msglen\n\t\t\tif postIndex > l {\n\t\t\t\treturn io.ErrUnexpectedEOF\n\t\t\t}\n\t\t\tif m.Setting == nil {\n\t\t\t\tm.Setting = &UserProtoResponse_Setting{}\n\t\t\t}\n\t\t\tif err := m.Setting.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tiNdEx = postIndex\n\t\tdefault:\n\t\t\tiNdEx = preIndex\n\t\t\tskippy, err := skipMessage(dAtA[iNdEx:])\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tif skippy < 0 {\n\t\t\t\treturn ErrInvalidLengthMessage\n\t\t\t}\n\t\t\tif (iNdEx + skippy) > l {\n\t\t\t\treturn io.ErrUnexpectedEOF\n\t\t\t}\n\t\t\tiNdEx += skippy\n\t\t}\n\t}\n\n\tif iNdEx > l {\n\t\treturn io.ErrUnexpectedEOF\n\t}\n\treturn nil\n}\nfunc (m *UserProtoResponse_Setting) Unmarshal(dAtA []byte) error {\n\tl := len(dAtA)\n\tiNdEx := 0\n\tfor iNdEx < l {\n\t\tpreIndex := iNdEx\n\t\tvar wire uint64\n\t\tfor shift := uint(0); ; shift += 7 {\n\t\t\tif shift >= 64 {\n\t\t\t\treturn ErrIntOverflowMessage\n\t\t\t}\n\t\t\tif iNdEx >= l {\n\t\t\t\treturn io.ErrUnexpectedEOF\n\t\t\t}\n\t\t\tb := dAtA[iNdEx]\n\t\t\tiNdEx++\n\t\t\twire |= (uint64(b) & 0x7F) << shift\n\t\t\tif b < 0x80 {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tfieldNum := int32(wire >> 3)\n\t\twireType := int(wire & 0x7)\n\t\tif wireType == 4 {\n\t\t\treturn fmt.Errorf(\"proto: Setting: wiretype end group for non-group\")\n\t\t}\n\t\tif fieldNum <= 0 {\n\t\t\treturn fmt.Errorf(\"proto: Setting: illegal tag %d (wire type %d)\", fieldNum, wire)\n\t\t}\n\t\tswitch fieldNum {\n\t\tcase 1:\n\t\t\tif wireType != 2 {\n\t\t\t\treturn fmt.Errorf(\"proto: wrong wireType = %d for field Email\", wireType)\n\t\t\t}\n\t\t\tvar stringLen uint64\n\t\t\tfor shift := uint(0); ; shift += 7 {\n\t\t\t\tif shift >= 64 {\n\t\t\t\t\treturn ErrIntOverflowMessage\n\t\t\t\t}\n\t\t\t\tif iNdEx >= l {\n\t\t\t\t\treturn io.ErrUnexpectedEOF\n\t\t\t\t}\n\t\t\t\tb := dAtA[iNdEx]\n\t\t\t\tiNdEx++\n\t\t\t\tstringLen |= (uint64(b) & 0x7F) << shift\n\t\t\t\tif b < 0x80 {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tintStringLen := int(stringLen)\n\t\t\tif intStringLen < 0 {\n\t\t\t\treturn ErrInvalidLengthMessage\n\t\t\t}\n\t\t\tpostIndex := iNdEx + intStringLen\n\t\t\tif postIndex > l {\n\t\t\t\treturn io.ErrUnexpectedEOF\n\t\t\t}\n\t\t\tm.Email = string(dAtA[iNdEx:postIndex])\n\t\t\tiNdEx = postIndex\n\t\tdefault:\n\t\t\tiNdEx = preIndex\n\t\t\tskippy, err := skipMessage(dAtA[iNdEx:])\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tif skippy < 0 {\n\t\t\t\treturn ErrInvalidLengthMessage\n\t\t\t}\n\t\t\tif (iNdEx + skippy) > l {\n\t\t\t\treturn io.ErrUnexpectedEOF\n\t\t\t}\n\t\t\tiNdEx += skippy\n\t\t}\n\t}\n\n\tif iNdEx > l {\n\t\treturn io.ErrUnexpectedEOF\n\t}\n\treturn nil\n}\nfunc skipMessage(dAtA []byte) (n int, err error) {\n\tl := len(dAtA)\n\tiNdEx := 0\n\tfor iNdEx < l {\n\t\tvar wire uint64\n\t\tfor shift := uint(0); ; shift += 7 {\n\t\t\tif shift >= 64 {\n\t\t\t\treturn 0, ErrIntOverflowMessage\n\t\t\t}\n\t\t\tif iNdEx >= l {\n\t\t\t\treturn 0, io.ErrUnexpectedEOF\n\t\t\t}\n\t\t\tb := dAtA[iNdEx]\n\t\t\tiNdEx++\n\t\t\twire |= (uint64(b) & 0x7F) << shift\n\t\t\tif b < 0x80 {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\twireType := int(wire & 0x7)\n\t\tswitch wireType {\n\t\tcase 0:\n\t\t\tfor shift := uint(0); ; shift += 7 {\n\t\t\t\tif shift >= 64 {\n\t\t\t\t\treturn 0, ErrIntOverflowMessage\n\t\t\t\t}\n\t\t\t\tif iNdEx >= l {\n\t\t\t\t\treturn 0, io.ErrUnexpectedEOF\n\t\t\t\t}\n\t\t\t\tiNdEx++\n\t\t\t\tif dAtA[iNdEx-1] < 0x80 {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn iNdEx, nil\n\t\tcase 1:\n\t\t\tiNdEx += 8\n\t\t\treturn iNdEx, nil\n\t\tcase 2:\n\t\t\tvar length int\n\t\t\tfor shift := uint(0); ; shift += 7 {\n\t\t\t\tif shift >= 64 {\n\t\t\t\t\treturn 0, ErrIntOverflowMessage\n\t\t\t\t}\n\t\t\t\tif iNdEx >= l {\n\t\t\t\t\treturn 0, io.ErrUnexpectedEOF\n\t\t\t\t}\n\t\t\t\tb := dAtA[iNdEx]\n\t\t\t\tiNdEx++\n\t\t\t\tlength |= (int(b) & 0x7F) << shift\n\t\t\t\tif b < 0x80 {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tiNdEx += length\n\t\t\tif length < 0 {\n\t\t\t\treturn 0, ErrInvalidLengthMessage\n\t\t\t}\n\t\t\treturn iNdEx, nil\n\t\tcase 3:\n\t\t\tfor {\n\t\t\t\tvar innerWire uint64\n\t\t\t\tvar start int = iNdEx\n\t\t\t\tfor shift := uint(0); ; shift += 7 {\n\t\t\t\t\tif shift >= 64 {\n\t\t\t\t\t\treturn 0, ErrIntOverflowMessage\n\t\t\t\t\t}\n\t\t\t\t\tif iNdEx >= l {\n\t\t\t\t\t\treturn 0, io.ErrUnexpectedEOF\n\t\t\t\t\t}\n\t\t\t\t\tb := dAtA[iNdEx]\n\t\t\t\t\tiNdEx++\n\t\t\t\t\tinnerWire |= (uint64(b) & 0x7F) << shift\n\t\t\t\t\tif b < 0x80 {\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tinnerWireType := int(innerWire & 0x7)\n\t\t\t\tif innerWireType == 4 {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tnext, err := skipMessage(dAtA[start:])\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn 0, err\n\t\t\t\t}\n\t\t\t\tiNdEx = start + next\n\t\t\t}\n\t\t\treturn iNdEx, nil\n\t\tcase 4:\n\t\t\treturn iNdEx, nil\n\t\tcase 5:\n\t\t\tiNdEx += 4\n\t\t\treturn iNdEx, nil\n\t\tdefault:\n\t\t\treturn 0, fmt.Errorf(\"proto: illegal wireType %d\", wireType)\n\t\t}\n\t}\n\tpanic(\"unreachable\")\n}\n\nvar (\n\tErrInvalidLengthMessage = fmt.Errorf(\"proto: negative length found during unmarshaling\")\n\tErrIntOverflowMessage   = fmt.Errorf(\"proto: integer overflow\")\n)\n\nfunc init() { proto.RegisterFile(\"message.proto\", fileDescriptorMessage) }\n\nvar fileDescriptorMessage = []byte{\n\t// 211 bytes of a gzipped FileDescriptorProto\n\t0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0xcd, 0x4d, 0x2d, 0x2e,\n\t0x4e, 0x4c, 0x4f, 0xd5, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0xcf, 0x28, 0x29, 0x29, 0x48,\n\t0xc9, 0x4f, 0x56, 0x32, 0xe3, 0x12, 0x08, 0x2d, 0x4e, 0x2d, 0x0a, 0x00, 0x89, 0x06, 0xa5, 0x16,\n\t0x96, 0xa6, 0x16, 0x97, 0x08, 0xf1, 0x71, 0x31, 0x65, 0xa6, 0x48, 0x30, 0x2a, 0x30, 0x6a, 0xb0,\n\t0x06, 0x31, 0x65, 0xa6, 0x08, 0x09, 0x71, 0xb1, 0xe4, 0x25, 0xe6, 0xa6, 0x4a, 0x30, 0x29, 0x30,\n\t0x6a, 0x70, 0x06, 0x81, 0xd9, 0x4a, 0xeb, 0x18, 0xb9, 0x04, 0x91, 0x34, 0x16, 0x17, 0xe4, 0xe7,\n\t0x15, 0xa7, 0x12, 0xa3, 0x53, 0x48, 0x8c, 0x8b, 0x2d, 0x31, 0xb9, 0x24, 0xb3, 0x2c, 0x55, 0x82,\n\t0x59, 0x81, 0x51, 0x83, 0x23, 0x08, 0xca, 0x13, 0xb2, 0xe1, 0x62, 0x2f, 0x4e, 0x2d, 0x29, 0xc9,\n\t0xcc, 0x4b, 0x97, 0x60, 0x51, 0x60, 0xd4, 0xe0, 0x36, 0x52, 0xd2, 0x83, 0x3a, 0x52, 0x0f, 0xc3,\n\t0x22, 0xbd, 0x60, 0x88, 0xca, 0x20, 0x98, 0x16, 0x29, 0x79, 0x2e, 0x76, 0xa8, 0x98, 0x90, 0x08,\n\t0x17, 0x6b, 0x6a, 0x6e, 0x62, 0x66, 0x0e, 0xd8, 0x1d, 0x9c, 0x41, 0x10, 0x8e, 0x93, 0xc0, 0x89,\n\t0x47, 0x72, 0x8c, 0x17, 0x1e, 0xc9, 0x31, 0x3e, 0x78, 0x24, 0xc7, 0x38, 0xe3, 0xb1, 0x1c, 0x43,\n\t0x12, 0x1b, 0x38, 0x28, 0x8c, 0x01, 0x01, 0x00, 0x00, 0xff, 0xff, 0xc5, 0x23, 0xb1, 0xd2, 0x1b,\n\t0x01, 0x00, 0x00,\n}\n"
  },
  {
    "path": "doc.go",
    "content": "// Package httpdoc is a Golang package for generating API documentation from httptest test cases.\n//\n// It provides a simple http middleware for recording various http requst & response values you use in your tests\n// and automatically arranges and generates them as usable documentation in markdown format. It also provides a way\n// to validate values are equal to what you expect with annotation (e.g., you can add a description for headers,\n// params or response fields).\n//\n// See example document output, https://github.com/mercari/go-httpdoc/blob/master/_example/doc/validate.md\npackage httpdoc // import \"go.mercari.io/go-httpdoc\"\n"
  },
  {
    "path": "httpdoc.go",
    "content": "package httpdoc\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"io\"\n\t\"io/ioutil\"\n\t\"log\"\n\t\"net/http\"\n\t\"os\"\n\t\"sort\"\n\n\t\"github.com/golang/protobuf/proto\"\n)\n\nconst (\n\t// EnvHTTPDoc is the environmental variable that determines if Generate func generates documentation\n\t// to the given file or not. By default, it does not generate. If this variable is not empty, then it does.\n\tEnvHTTPDoc = \"HTTPDOC\"\n)\n\n// Document stores recorded results by Record middleware.\ntype Document struct {\n\t// Name is API documentation name.\n\tName string\n\n\t// ExcludeHeaders is list of headers to exclude from documentation.\n\t// For example, you may do not need `Content-Length` header. This is applied all entries (endpoints).\n\t// If you want to exclude header only in specific endpoint, then use `RecordOption.ExcludeHeaders`.\n\tExcludeHeaders []string\n\n\t// Entries stores all recorded results by Record middleware. Normally, you don't need to modify this.\n\t// This is exported just for templating.\n\tEntries []Entry\n\n\t// tmpl is template file to use. Currently this is only static/tmpl/doc.md.tmpl\n\ttmpl string\n\n\tlogger *log.Logger\n}\n\n// Entry is recorded results by Record middleware. Normally, you don't need to modify this.\n// All fields are exported just for templating.\ntype Entry struct {\n\t// Description is description of endpoint.\n\tDescription string\n\n\t// Method is HTTP method.\n\tMethod string\n\n\t// Path is request path.\n\tPath string\n\n\tRequestParams  []Data\n\tRequestHeaders []Data\n\tRequestFields  []Data\n\n\t// RequestExample is request body example. If you use plain text for json for response body\n\t// it uses it here without modification. If you use protocol buffer format for your request body\n\t// it unmarshals it in the given struct and encodes it into json format.\n\tRequestExample string\n\n\tResponseStatusCode int\n\tResponseHeaders    []Data\n\tResponseFields     []Data\n\n\t// ResponseExample is response body example. If you use plain text for json for response body\n\t// it uses it here without modification. If you use protocol buffer format for your response body\n\t// it unmarshals it in the given struct and encodes it into json format.\n\tResponseExample string\n}\n\n// RecordOption is option for Record middleware.\ntype RecordOption struct {\n\t// Description is description of endpoint. This is used for Entry.Description.\n\tDescription string\n\n\t// ExcludeHeaders is list of headers to exclude from documentation.\n\t// This is applied only one entry (endpoint). If you want to exclude header in all endpoints\n\t// use `Document.ExcludeHeaders`.\n\tExcludeHeaders []string\n\n\t// WithValidate option, you can validate various http request & response parameter values.\n\t// It inspects values which handler receives and checks it's expected or not.\n\t// If not it asserts and fails the test. If ok, uses it for documentation entry.\n\t//\n\t// Not only validate, you can add an annotation to each values (e.g., what does the header\n\t// means?) and it's used for documentation.\n\t//\n\t// See more usage in Validator methods.\n\tWithValidate func(*Validator)\n\n\t// WithProtoBuffer option is used for protocol buffer request & response.\n\tWithProtoBuffer *ProtoBufferOption\n}\n\n// ProtoBufferOption is option for protocol buffer.\ntype ProtoBufferOption struct {\n\t// RequestUnmarshaler is used to unmarshal protocol buffer encoded request body.\n\t// This is used for generating human readable request example (json format).\n\tRequestUnmarshaler proto.Unmarshaler\n\n\t// ResponseUnmarshaler is used to unmarshal protocol buffer encoded response body.\n\t// This is used for generating human readable response example (json format).\n\tResponseUnmarshaler proto.Unmarshaler\n}\n\n// Data represents a request or response parameter value. Normally, you don't need to modify this.\n// All fields are exported just for templating.\ntype Data struct {\n\t// Name is header or params, field name.\n\tName string\n\n\t// Value is actual value handler receives.\n\tValue interface{}\n\n\t// Description is description for this data. You can provide this via a validator.\n\tDescription string\n}\n\ntype byName []Data\n\nfunc (n byName) Len() int           { return len(n) }\nfunc (n byName) Less(i, j int) bool { return n[i].Name < n[j].Name }\nfunc (n byName) Swap(i, j int)      { n[i], n[j] = n[j], n[i] }\n\n// Record is a http middleware. It records all request & response values which the given http handler\n// receives & response and save it in the given Document.\nfunc Record(next http.Handler, document *Document, opt *RecordOption) http.Handler {\n\n\t// If not option is provided, initialize it.\n\tif opt == nil {\n\t\topt = &RecordOption{}\n\t}\n\n\tif document.logger == nil {\n\t\tdocument.logger = log.New(os.Stderr, \"\", log.LstdFlags)\n\t}\n\n\treturn http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n\t\t// Create a new responseWriter it captures status code and response body.\n\t\trw := responseWriter{\n\t\t\tResponseWriter: w,\n\t\t}\n\n\t\t// Create a tee reader and stores request body.\n\t\t// Because of this, handler must read request body to record.\n\t\tvar requestBody bytes.Buffer\n\t\tr.Body = ioutil.NopCloser(io.TeeReader(r.Body, &requestBody))\n\n\t\tnext.ServeHTTP(&rw, r)\n\n\t\t// If protobuffer option is provided, use protoUnmarshalFunc for\n\t\t// validator, by default, use json unmashal func.\n\t\tunmarshalFunc := defaultUnmarshalFunc\n\t\tif opt.WithProtoBuffer != nil {\n\t\t\tunmarshalFunc = protoUnmarshalFunc\n\t\t}\n\n\t\tvalidator := &Validator{\n\t\t\trecord: &record{\n\t\t\t\trequestParams:  r.URL.Query(),\n\t\t\t\trequestHeaders: r.Header,\n\t\t\t\trequestBody:    requestBody.Bytes(),\n\n\t\t\t\tresponseStatusCode: rw.statusCode,\n\t\t\t\tresponseHeaders:    rw.Header(),\n\t\t\t\tresponseBody:       rw.responseBody,\n\t\t\t},\n\t\t\tunmarshalFunc: unmarshalFunc,\n\t\t\tassertFunc:    defaultAssertFunc,\n\t\t}\n\n\t\tif opt.WithValidate != nil {\n\t\t\topt.WithValidate(validator)\n\t\t}\n\n\t\texcludeHeaders := append(opt.ExcludeHeaders, document.ExcludeHeaders...)\n\n\t\trequestParams := mergeData(validator.requestParams, convertHeaders(r.URL.Query()))\n\n\t\trequestHeaders := mergeData(validator.requestHeaders, convertHeaders(r.Header))\n\t\trequestHeaders = excludeData(requestHeaders, excludeHeaders)\n\n\t\tresponseHeaders := mergeData(validator.responseHeaders, convertHeaders(rw.Header()))\n\t\tresponseHeaders = excludeData(responseHeaders, excludeHeaders)\n\n\t\trequestExample := requestBody.String()\n\t\tresponseExample := string(rw.responseBody)\n\t\tif opt.WithProtoBuffer != nil {\n\t\t\t// FIXME(tcnksm): Want to use jsonpb but sometimes panic happens while marshalling....\n\t\t\tif unmarshaler := opt.WithProtoBuffer.RequestUnmarshaler; unmarshaler != nil {\n\t\t\t\tunmarshaler.Unmarshal(requestBody.Bytes())\n\n\t\t\t\tvar buf bytes.Buffer\n\t\t\t\tencoder := json.NewEncoder(&buf)\n\t\t\t\tencoder.Encode(unmarshaler)\n\t\t\t\ts := buf.String()\n\t\t\t\tbuf.Reset()\n\t\t\t\tjson.Indent(&buf, []byte(s), \"\", \"  \")\n\n\t\t\t\trequestExample = buf.String()\n\t\t\t}\n\n\t\t\tif unmarshaler := opt.WithProtoBuffer.ResponseUnmarshaler; unmarshaler != nil {\n\t\t\t\tunmarshaler.Unmarshal(rw.responseBody)\n\n\t\t\t\tvar buf bytes.Buffer\n\t\t\t\tencoder := json.NewEncoder(&buf)\n\t\t\t\tencoder.Encode(unmarshaler)\n\t\t\t\ts := buf.String()\n\t\t\t\tbuf.Reset()\n\t\t\t\tjson.Indent(&buf, []byte(s), \"\", \"  \")\n\n\t\t\t\tresponseExample = buf.String()\n\t\t\t}\n\t\t}\n\n\t\tentry := Entry{\n\t\t\tDescription: opt.Description,\n\n\t\t\tMethod: r.Method,\n\t\t\tPath:   r.URL.Path,\n\n\t\t\tRequestHeaders: requestHeaders,\n\t\t\tRequestParams:  requestParams,\n\t\t\tRequestFields:  validator.requestFields,\n\t\t\tRequestExample: requestExample,\n\n\t\t\tResponseStatusCode: rw.statusCode,\n\t\t\tResponseHeaders:    responseHeaders,\n\t\t\tResponseFields:     validator.responseFields,\n\t\t\tResponseExample:    responseExample,\n\t\t}\n\t\tentry.format()\n\t\tdocument.Entries = append(document.Entries, entry)\n\t})\n}\n\n// format sorts entry data to prevent results updated everytime.\nfunc (e *Entry) format() error {\n\tsort.Sort(byName(e.RequestHeaders))\n\tsort.Sort(byName(e.RequestParams))\n\n\treturn nil\n}\n\ntype responseWriter struct {\n\tstatusCode   int\n\tresponseBody []byte\n\n\thttp.ResponseWriter\n}\n\nfunc (w *responseWriter) Write(buf []byte) (int, error) {\n\tw.responseBody = buf\n\treturn w.ResponseWriter.Write(buf)\n}\n\nfunc (w *responseWriter) WriteHeader(code int) {\n\tw.statusCode = code\n\tw.ResponseWriter.WriteHeader(code)\n}\n\n// convertHeaders convert HTTP header to httpdoc description format.\nfunc convertHeaders(headers map[string][]string) []Data {\n\td := make([]Data, 0, len(headers))\n\tfor k, v := range headers {\n\t\tdata := Data{\n\t\t\tName:  k,\n\t\t\tValue: v[0],\n\t\t}\n\t\td = append(d, data)\n\t}\n\treturn d\n}\n\n// mergeData merges 2 Data slice into 1 slice without duplication.\n// If duplicated, item in 1st slice is used.\nfunc mergeData(a, b []Data) []Data {\n\tnewData := make([]Data, len(a))\n\tcopy(newData, a)\n\tfor _, d1 := range b {\n\t\tvar contain bool\n\t\tfor _, d2 := range a {\n\t\t\tif d1.Name == d2.Name {\n\t\t\t\tcontain = true\n\t\t\t}\n\t\t}\n\t\tif !contain {\n\t\t\tnewData = append(newData, d1)\n\t\t}\n\t}\n\treturn newData\n}\n\n// excludeData excludes data which is given.\nfunc excludeData(target []Data, excludes ...[]string) []Data {\n\tnewData := make([]Data, 0, len(target))\n\tfor _, d := range target {\n\t\tvar contain bool\n\t\tfor _, exclude := range excludes {\n\t\t\tfor _, name := range exclude {\n\t\t\t\tif d.Name == name {\n\t\t\t\t\tcontain = true\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif !contain {\n\t\t\tnewData = append(newData, d)\n\t\t}\n\t}\n\treturn newData\n}\n"
  },
  {
    "path": "httpdoc_test.go",
    "content": "package httpdoc\n\nimport (\n\t\"bytes\"\n\t\"io\"\n\t\"io/ioutil\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"reflect\"\n\t\"sort\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/golang/protobuf/proto\"\n)\n\nvar (\n\ttestExcludeHeaders = []string{\"User-Agent\", \"Accept-Encoding\", \"Content-Length\"}\n\n\ttestHandler = func(w http.ResponseWriter, r *http.Request) {\n\t\t// To record, request example, request body must be read in handler\n\t\tio.Copy(ioutil.Discard, r.Body)\n\n\t\tw.WriteHeader(http.StatusOK)\n\t\tw.Header().Add(\"Content-Type\", \"text/plain\")\n\t\tw.Write([]byte(\"hello\"))\n\t}\n\n\ttestHandlerProto = func(w http.ResponseWriter, r *http.Request) {\n\t\t// To record, request example, request body must be read in handler\n\t\tio.Copy(ioutil.Discard, r.Body)\n\n\t\tresponse := &UserProtoResponse{\n\t\t\tId:     7089,\n\t\t\tName:   \"tcnksm\",\n\t\t\tActive: true,\n\t\t}\n\t\tbuf, _ := response.Marshal()\n\n\t\tw.WriteHeader(http.StatusOK)\n\t\tw.Header().Add(\"Content-Type\", \"application/protobuf\")\n\t\tw.Write(buf)\n\t}\n)\n\nfunc TestRecord(t *testing.T) {\n\tcases := []struct {\n\t\tpath          string\n\t\thandler       http.HandlerFunc\n\t\trecordOption  *RecordOption\n\t\trequestMethod string\n\t\trequestParam  string\n\t\trequestBody   io.Reader\n\t\twant          Entry\n\t}{\n\t\t{\n\t\t\t\"/v1/hello\",\n\t\t\ttestHandler,\n\t\t\tnil,\n\t\t\t\"GET\",\n\t\t\t\"?token=123456&pretty=true\",\n\t\t\tstrings.NewReader(\"hello\"),\n\t\t\tEntry{\n\t\t\t\tDescription: \"\",\n\t\t\t\tMethod:      \"GET\",\n\t\t\t\tPath:        \"/v1/hello\",\n\n\t\t\t\tRequestParams: []Data{\n\t\t\t\t\t{\"pretty\", \"true\", \"\"},\n\t\t\t\t\t{\"token\", \"123456\", \"\"},\n\t\t\t\t},\n\t\t\t\tRequestHeaders: []Data{\n\t\t\t\t\t{\"Accept-Encoding\", \"gzip\", \"\"},\n\t\t\t\t\t{\"Content-Length\", \"5\", \"\"},\n\t\t\t\t\t{\"User-Agent\", \"Go-http-client/1.1\", \"\"},\n\t\t\t\t},\n\t\t\t\tRequestFields:  nil,\n\t\t\t\tRequestExample: \"hello\",\n\n\t\t\t\tResponseStatusCode: http.StatusOK,\n\t\t\t\tResponseHeaders: []Data{\n\t\t\t\t\t{\"Content-Type\", \"text/plain\", \"\"},\n\t\t\t\t},\n\t\t\t\tResponseExample: \"hello\",\n\t\t\t},\n\t\t},\n\n\t\t{\n\t\t\t\"/v1/hello\",\n\t\t\ttestHandler,\n\t\t\t&RecordOption{\n\t\t\t\tExcludeHeaders: testExcludeHeaders,\n\t\t\t},\n\t\t\t\"GET\",\n\t\t\t\"\",\n\t\t\tstrings.NewReader(\"hello\"),\n\t\t\tEntry{\n\t\t\t\tDescription: \"\",\n\t\t\t\tMethod:      \"GET\",\n\t\t\t\tPath:        \"/v1/hello\",\n\n\t\t\t\tRequestParams:  []Data{},\n\t\t\t\tRequestHeaders: []Data{},\n\t\t\t\tRequestFields:  nil,\n\t\t\t\tRequestExample: \"hello\",\n\n\t\t\t\tResponseStatusCode: http.StatusOK,\n\t\t\t\tResponseHeaders: []Data{\n\t\t\t\t\t{\"Content-Type\", \"text/plain\", \"\"},\n\t\t\t\t},\n\t\t\t\tResponseExample: \"hello\",\n\t\t\t},\n\t\t},\n\n\t\t{\n\t\t\t\"/v1/hello\",\n\t\t\ttestHandler,\n\t\t\t&RecordOption{\n\t\t\t\tExcludeHeaders: testExcludeHeaders,\n\t\t\t\tWithValidate: func(v *Validator) {\n\t\t\t\t\tv.RequestParams(t, []TestCase{\n\t\t\t\t\t\tNewTestCase(\"token\", \"123456\", \"Test token\"),\n\t\t\t\t\t})\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"GET\",\n\t\t\t\"?token=123456\",\n\t\t\tstrings.NewReader(\"hello\"),\n\t\t\tEntry{\n\t\t\t\tDescription: \"\",\n\t\t\t\tMethod:      \"GET\",\n\t\t\t\tPath:        \"/v1/hello\",\n\n\t\t\t\tRequestParams: []Data{\n\t\t\t\t\t{\"token\", \"123456\", \"Test token\"},\n\t\t\t\t},\n\t\t\t\tRequestHeaders: []Data{},\n\t\t\t\tRequestFields:  nil,\n\t\t\t\tRequestExample: \"hello\",\n\n\t\t\t\tResponseStatusCode: http.StatusOK,\n\t\t\t\tResponseHeaders: []Data{\n\t\t\t\t\t{\"Content-Type\", \"text/plain\", \"\"},\n\t\t\t\t},\n\t\t\t\tResponseExample: \"hello\",\n\t\t\t},\n\t\t},\n\t}\n\n\tfor _, tc := range cases {\n\t\tdocument := &Document{}\n\t\tmux := http.NewServeMux()\n\t\tmux.Handle(tc.path, Record(tc.handler, document, tc.recordOption))\n\t\ttestServer := httptest.NewServer(mux)\n\n\t\tclient := http.DefaultClient\n\t\treq, err := http.NewRequest(tc.requestMethod, testServer.URL+tc.path+tc.requestParam, tc.requestBody)\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\n\t\tif _, err := client.Do(req); err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\n\t\tif len(document.Entries) != 1 {\n\t\t\tt.Fatalf(\"expect doc records 1 entry\")\n\t\t}\n\n\t\tgot := document.Entries[0]\n\t\tif !reflect.DeepEqual(got, tc.want) {\n\t\t\tt.Fatalf(\"\\ngot  %#v\\nwant %#v\", got, tc.want)\n\t\t}\n\t\ttestServer.Close()\n\t}\n}\n\nfunc TestRecord_Proto(t *testing.T) {\n\tcases := []struct {\n\t\tpath          string\n\t\thandler       http.HandlerFunc\n\t\trecordOption  *RecordOption\n\t\trequestMethod string\n\t\trequestParam  string\n\t\trequestBody   proto.Marshaler\n\t\twant          Entry\n\t}{\n\t\t{\n\t\t\t\"/v1/hello_proto\",\n\t\t\ttestHandlerProto,\n\t\t\t&RecordOption{\n\t\t\t\tExcludeHeaders: testExcludeHeaders,\n\t\t\t\tWithProtoBuffer: &ProtoBufferOption{\n\t\t\t\t\tRequestUnmarshaler:  &UserProtoRequest{},\n\t\t\t\t\tResponseUnmarshaler: &UserProtoResponse{},\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"GET\",\n\t\t\t\"\",\n\t\t\t&UserProtoRequest{\n\t\t\t\tId:   7089,\n\t\t\t\tName: \"tcnksm\",\n\t\t\t},\n\t\t\tEntry{\n\t\t\t\tDescription: \"\",\n\t\t\t\tMethod:      \"GET\",\n\t\t\t\tPath:        \"/v1/hello_proto\",\n\n\t\t\t\tRequestParams:  []Data{},\n\t\t\t\tRequestHeaders: []Data{},\n\t\t\t\tRequestFields:  nil,\n\t\t\t\tRequestExample: `{\n  \"id\": 7089,\n  \"name\": \"tcnksm\"\n}\n`,\n\n\t\t\t\tResponseStatusCode: http.StatusOK,\n\t\t\t\tResponseHeaders: []Data{\n\t\t\t\t\t{\"Content-Type\", \"application/protobuf\", \"\"},\n\t\t\t\t},\n\t\t\t\tResponseExample: `{\n  \"id\": 7089,\n  \"name\": \"tcnksm\",\n  \"active\": true\n}\n`,\n\t\t\t},\n\t\t},\n\t}\n\n\tfor _, tc := range cases {\n\t\tdocument := &Document{}\n\t\tmux := http.NewServeMux()\n\t\tmux.Handle(tc.path, Record(tc.handler, document, tc.recordOption))\n\t\ttestServer := httptest.NewServer(mux)\n\n\t\tclient := http.DefaultClient\n\t\tbuf, err := tc.requestBody.Marshal()\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\treq, err := http.NewRequest(tc.requestMethod, testServer.URL+tc.path+tc.requestParam, bytes.NewReader(buf))\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\n\t\tif _, err := client.Do(req); err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\n\t\tif len(document.Entries) != 1 {\n\t\t\tt.Fatalf(\"expect doc records 1 entry\")\n\t\t}\n\n\t\tgot := document.Entries[0]\n\t\tif !reflect.DeepEqual(got, tc.want) {\n\t\t\tt.Fatalf(\"\\ngot  %#v\\nwant %#v\", got, tc.want)\n\t\t}\n\t\ttestServer.Close()\n\t}\n}\n\nfunc TestConvertHeaders(t *testing.T) {\n\tinput := map[string][]string{\n\t\t\"Content-Type\":  []string{\"application/json\"},\n\t\t\"X-API-Version\": []string{\"1.1.2\"},\n\t}\n\n\tgot := convertHeaders(input)\n\twant := []Data{\n\t\t{\n\t\t\tName:        \"Content-Type\",\n\t\t\tValue:       \"application/json\",\n\t\t\tDescription: \"\",\n\t\t},\n\t\t{\n\t\t\tName:        \"X-API-Version\",\n\t\t\tValue:       \"1.1.2\",\n\t\t\tDescription: \"\",\n\t\t},\n\t}\n\n\tsort.Sort(byName(got))\n\n\tif !reflect.DeepEqual(got, want) {\n\t\tt.Fatalf(\"got %#v, want %#v\", got, want)\n\t}\n}\n\nfunc TestMergeData(t *testing.T) {\n\ta := []Data{\n\t\t{Name: \"1\"},\n\t\t{Name: \"2\"},\n\t\t{Name: \"3\", Description: \"this is 3\"},\n\t\t{Name: \"4\", Description: \"this is 4\"},\n\t}\n\n\tb := []Data{\n\t\t{Name: \"3\"},\n\t\t{Name: \"4\"},\n\t\t{Name: \"5\"},\n\t}\n\n\tgot := mergeData(a, b)\n\twant := []Data{\n\t\t{Name: \"1\"},\n\t\t{Name: \"2\"},\n\t\t{Name: \"3\", Description: \"this is 3\"},\n\t\t{Name: \"4\", Description: \"this is 4\"},\n\t\t{Name: \"5\"},\n\t}\n\n\tif !reflect.DeepEqual(got, want) {\n\t\tt.Fatalf(\"got %#v, want %#v\", got, want)\n\t}\n}\n\nfunc TestExcludeData(t *testing.T) {\n\tinput := []Data{\n\t\t{Name: \"1\"},\n\t\t{Name: \"2\"},\n\t\t{Name: \"3\"},\n\t\t{Name: \"4\"},\n\t\t{Name: \"5\"},\n\t}\n\n\tgot := excludeData(input, []string{\"1\", \"2\"}, []string{\"3\"}, []string{\"4\"})\n\twant := []Data{\n\t\t{\n\t\t\tName: \"5\",\n\t\t},\n\t}\n\n\tif !reflect.DeepEqual(got, want) {\n\t\tt.Fatalf(\"got %#v, want %#v\", got, want)\n\t}\n}\n\nfunc TestResponseWriter_Write(t *testing.T) {\n}\n\nfunc TestResponseWriter_WriteHeader(t *testing.T) {\n}\n"
  },
  {
    "path": "message_pb_test.go",
    "content": "// Code generated by protoc-gen-gogo.\n// source: message.proto\n// DO NOT EDIT!\n\n/*\n\tPackage httpdoc is a generated protocol buffer package.\n\n\tIt is generated from these files:\n\t\tmessage.proto\n\n\tIt has these top-level messages:\n\t\tUserProtoRequest\n\t\tUserProtoResponse\n*/\npackage httpdoc\n\nimport proto \"github.com/golang/protobuf/proto\"\nimport fmt \"fmt\"\nimport math \"math\"\n\nimport io \"io\"\n\n// Reference imports to suppress errors if they are not otherwise used.\nvar _ = proto.Marshal\nvar _ = fmt.Errorf\nvar _ = math.Inf\n\n// This is a compile-time assertion to ensure that this generated file\n// is compatible with the proto package it is being compiled against.\n// A compilation error at this line likely means your copy of the\n// proto package needs to be updated.\nconst _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package\n\ntype UserProtoRequest struct {\n\tId   int32  `protobuf:\"varint,1,opt,name=id,proto3\" json:\"id,omitempty\"`\n\tName string `protobuf:\"bytes,2,opt,name=name,proto3\" json:\"name,omitempty\"`\n}\n\nfunc (m *UserProtoRequest) Reset()                    { *m = UserProtoRequest{} }\nfunc (m *UserProtoRequest) String() string            { return proto.CompactTextString(m) }\nfunc (*UserProtoRequest) ProtoMessage()               {}\nfunc (*UserProtoRequest) Descriptor() ([]byte, []int) { return fileDescriptorMessage, []int{0} }\n\nfunc (m *UserProtoRequest) GetId() int32 {\n\tif m != nil {\n\t\treturn m.Id\n\t}\n\treturn 0\n}\n\nfunc (m *UserProtoRequest) GetName() string {\n\tif m != nil {\n\t\treturn m.Name\n\t}\n\treturn \"\"\n}\n\ntype UserProtoResponse struct {\n\tId      int32                      `protobuf:\"varint,1,opt,name=id,proto3\" json:\"id,omitempty\"`\n\tName    string                     `protobuf:\"bytes,2,opt,name=name,proto3\" json:\"name,omitempty\"`\n\tActive  bool                       `protobuf:\"varint,3,opt,name=active,proto3\" json:\"active,omitempty\"`\n\tSetting *UserProtoResponse_Setting `protobuf:\"bytes,4,opt,name=setting\" json:\"setting,omitempty\"`\n}\n\nfunc (m *UserProtoResponse) Reset()                    { *m = UserProtoResponse{} }\nfunc (m *UserProtoResponse) String() string            { return proto.CompactTextString(m) }\nfunc (*UserProtoResponse) ProtoMessage()               {}\nfunc (*UserProtoResponse) Descriptor() ([]byte, []int) { return fileDescriptorMessage, []int{1} }\n\nfunc (m *UserProtoResponse) GetId() int32 {\n\tif m != nil {\n\t\treturn m.Id\n\t}\n\treturn 0\n}\n\nfunc (m *UserProtoResponse) GetName() string {\n\tif m != nil {\n\t\treturn m.Name\n\t}\n\treturn \"\"\n}\n\nfunc (m *UserProtoResponse) GetActive() bool {\n\tif m != nil {\n\t\treturn m.Active\n\t}\n\treturn false\n}\n\nfunc (m *UserProtoResponse) GetSetting() *UserProtoResponse_Setting {\n\tif m != nil {\n\t\treturn m.Setting\n\t}\n\treturn nil\n}\n\ntype UserProtoResponse_Setting struct {\n\tEmail string `protobuf:\"bytes,1,opt,name=email,proto3\" json:\"email,omitempty\"`\n}\n\nfunc (m *UserProtoResponse_Setting) Reset()         { *m = UserProtoResponse_Setting{} }\nfunc (m *UserProtoResponse_Setting) String() string { return proto.CompactTextString(m) }\nfunc (*UserProtoResponse_Setting) ProtoMessage()    {}\nfunc (*UserProtoResponse_Setting) Descriptor() ([]byte, []int) {\n\treturn fileDescriptorMessage, []int{1, 0}\n}\n\nfunc (m *UserProtoResponse_Setting) GetEmail() string {\n\tif m != nil {\n\t\treturn m.Email\n\t}\n\treturn \"\"\n}\n\nfunc init() {\n\tproto.RegisterType((*UserProtoRequest)(nil), \"httpdoc.UserProtoRequest\")\n\tproto.RegisterType((*UserProtoResponse)(nil), \"httpdoc.UserProtoResponse\")\n\tproto.RegisterType((*UserProtoResponse_Setting)(nil), \"httpdoc.UserProtoResponse.Setting\")\n}\nfunc (m *UserProtoRequest) Marshal() (dAtA []byte, err error) {\n\tsize := m.Size()\n\tdAtA = make([]byte, size)\n\tn, err := m.MarshalTo(dAtA)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn dAtA[:n], nil\n}\n\nfunc (m *UserProtoRequest) MarshalTo(dAtA []byte) (int, error) {\n\tvar i int\n\t_ = i\n\tvar l int\n\t_ = l\n\tif m.Id != 0 {\n\t\tdAtA[i] = 0x8\n\t\ti++\n\t\ti = encodeVarintMessage(dAtA, i, uint64(m.Id))\n\t}\n\tif len(m.Name) > 0 {\n\t\tdAtA[i] = 0x12\n\t\ti++\n\t\ti = encodeVarintMessage(dAtA, i, uint64(len(m.Name)))\n\t\ti += copy(dAtA[i:], m.Name)\n\t}\n\treturn i, nil\n}\n\nfunc (m *UserProtoResponse) Marshal() (dAtA []byte, err error) {\n\tsize := m.Size()\n\tdAtA = make([]byte, size)\n\tn, err := m.MarshalTo(dAtA)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn dAtA[:n], nil\n}\n\nfunc (m *UserProtoResponse) MarshalTo(dAtA []byte) (int, error) {\n\tvar i int\n\t_ = i\n\tvar l int\n\t_ = l\n\tif m.Id != 0 {\n\t\tdAtA[i] = 0x8\n\t\ti++\n\t\ti = encodeVarintMessage(dAtA, i, uint64(m.Id))\n\t}\n\tif len(m.Name) > 0 {\n\t\tdAtA[i] = 0x12\n\t\ti++\n\t\ti = encodeVarintMessage(dAtA, i, uint64(len(m.Name)))\n\t\ti += copy(dAtA[i:], m.Name)\n\t}\n\tif m.Active {\n\t\tdAtA[i] = 0x18\n\t\ti++\n\t\tif m.Active {\n\t\t\tdAtA[i] = 1\n\t\t} else {\n\t\t\tdAtA[i] = 0\n\t\t}\n\t\ti++\n\t}\n\tif m.Setting != nil {\n\t\tdAtA[i] = 0x22\n\t\ti++\n\t\ti = encodeVarintMessage(dAtA, i, uint64(m.Setting.Size()))\n\t\tn1, err := m.Setting.MarshalTo(dAtA[i:])\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\ti += n1\n\t}\n\treturn i, nil\n}\n\nfunc (m *UserProtoResponse_Setting) Marshal() (dAtA []byte, err error) {\n\tsize := m.Size()\n\tdAtA = make([]byte, size)\n\tn, err := m.MarshalTo(dAtA)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn dAtA[:n], nil\n}\n\nfunc (m *UserProtoResponse_Setting) MarshalTo(dAtA []byte) (int, error) {\n\tvar i int\n\t_ = i\n\tvar l int\n\t_ = l\n\tif len(m.Email) > 0 {\n\t\tdAtA[i] = 0xa\n\t\ti++\n\t\ti = encodeVarintMessage(dAtA, i, uint64(len(m.Email)))\n\t\ti += copy(dAtA[i:], m.Email)\n\t}\n\treturn i, nil\n}\n\nfunc encodeFixed64Message(dAtA []byte, offset int, v uint64) int {\n\tdAtA[offset] = uint8(v)\n\tdAtA[offset+1] = uint8(v >> 8)\n\tdAtA[offset+2] = uint8(v >> 16)\n\tdAtA[offset+3] = uint8(v >> 24)\n\tdAtA[offset+4] = uint8(v >> 32)\n\tdAtA[offset+5] = uint8(v >> 40)\n\tdAtA[offset+6] = uint8(v >> 48)\n\tdAtA[offset+7] = uint8(v >> 56)\n\treturn offset + 8\n}\nfunc encodeFixed32Message(dAtA []byte, offset int, v uint32) int {\n\tdAtA[offset] = uint8(v)\n\tdAtA[offset+1] = uint8(v >> 8)\n\tdAtA[offset+2] = uint8(v >> 16)\n\tdAtA[offset+3] = uint8(v >> 24)\n\treturn offset + 4\n}\nfunc encodeVarintMessage(dAtA []byte, offset int, v uint64) int {\n\tfor v >= 1<<7 {\n\t\tdAtA[offset] = uint8(v&0x7f | 0x80)\n\t\tv >>= 7\n\t\toffset++\n\t}\n\tdAtA[offset] = uint8(v)\n\treturn offset + 1\n}\nfunc (m *UserProtoRequest) Size() (n int) {\n\tvar l int\n\t_ = l\n\tif m.Id != 0 {\n\t\tn += 1 + sovMessage(uint64(m.Id))\n\t}\n\tl = len(m.Name)\n\tif l > 0 {\n\t\tn += 1 + l + sovMessage(uint64(l))\n\t}\n\treturn n\n}\n\nfunc (m *UserProtoResponse) Size() (n int) {\n\tvar l int\n\t_ = l\n\tif m.Id != 0 {\n\t\tn += 1 + sovMessage(uint64(m.Id))\n\t}\n\tl = len(m.Name)\n\tif l > 0 {\n\t\tn += 1 + l + sovMessage(uint64(l))\n\t}\n\tif m.Active {\n\t\tn += 2\n\t}\n\tif m.Setting != nil {\n\t\tl = m.Setting.Size()\n\t\tn += 1 + l + sovMessage(uint64(l))\n\t}\n\treturn n\n}\n\nfunc (m *UserProtoResponse_Setting) Size() (n int) {\n\tvar l int\n\t_ = l\n\tl = len(m.Email)\n\tif l > 0 {\n\t\tn += 1 + l + sovMessage(uint64(l))\n\t}\n\treturn n\n}\n\nfunc sovMessage(x uint64) (n int) {\n\tfor {\n\t\tn++\n\t\tx >>= 7\n\t\tif x == 0 {\n\t\t\tbreak\n\t\t}\n\t}\n\treturn n\n}\nfunc sozMessage(x uint64) (n int) {\n\treturn sovMessage(uint64((x << 1) ^ uint64((int64(x) >> 63))))\n}\nfunc (m *UserProtoRequest) Unmarshal(dAtA []byte) error {\n\tl := len(dAtA)\n\tiNdEx := 0\n\tfor iNdEx < l {\n\t\tpreIndex := iNdEx\n\t\tvar wire uint64\n\t\tfor shift := uint(0); ; shift += 7 {\n\t\t\tif shift >= 64 {\n\t\t\t\treturn ErrIntOverflowMessage\n\t\t\t}\n\t\t\tif iNdEx >= l {\n\t\t\t\treturn io.ErrUnexpectedEOF\n\t\t\t}\n\t\t\tb := dAtA[iNdEx]\n\t\t\tiNdEx++\n\t\t\twire |= (uint64(b) & 0x7F) << shift\n\t\t\tif b < 0x80 {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tfieldNum := int32(wire >> 3)\n\t\twireType := int(wire & 0x7)\n\t\tif wireType == 4 {\n\t\t\treturn fmt.Errorf(\"proto: UserProtoRequest: wiretype end group for non-group\")\n\t\t}\n\t\tif fieldNum <= 0 {\n\t\t\treturn fmt.Errorf(\"proto: UserProtoRequest: illegal tag %d (wire type %d)\", fieldNum, wire)\n\t\t}\n\t\tswitch fieldNum {\n\t\tcase 1:\n\t\t\tif wireType != 0 {\n\t\t\t\treturn fmt.Errorf(\"proto: wrong wireType = %d for field Id\", wireType)\n\t\t\t}\n\t\t\tm.Id = 0\n\t\t\tfor shift := uint(0); ; shift += 7 {\n\t\t\t\tif shift >= 64 {\n\t\t\t\t\treturn ErrIntOverflowMessage\n\t\t\t\t}\n\t\t\t\tif iNdEx >= l {\n\t\t\t\t\treturn io.ErrUnexpectedEOF\n\t\t\t\t}\n\t\t\t\tb := dAtA[iNdEx]\n\t\t\t\tiNdEx++\n\t\t\t\tm.Id |= (int32(b) & 0x7F) << shift\n\t\t\t\tif b < 0x80 {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\tcase 2:\n\t\t\tif wireType != 2 {\n\t\t\t\treturn fmt.Errorf(\"proto: wrong wireType = %d for field Name\", wireType)\n\t\t\t}\n\t\t\tvar stringLen uint64\n\t\t\tfor shift := uint(0); ; shift += 7 {\n\t\t\t\tif shift >= 64 {\n\t\t\t\t\treturn ErrIntOverflowMessage\n\t\t\t\t}\n\t\t\t\tif iNdEx >= l {\n\t\t\t\t\treturn io.ErrUnexpectedEOF\n\t\t\t\t}\n\t\t\t\tb := dAtA[iNdEx]\n\t\t\t\tiNdEx++\n\t\t\t\tstringLen |= (uint64(b) & 0x7F) << shift\n\t\t\t\tif b < 0x80 {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tintStringLen := int(stringLen)\n\t\t\tif intStringLen < 0 {\n\t\t\t\treturn ErrInvalidLengthMessage\n\t\t\t}\n\t\t\tpostIndex := iNdEx + intStringLen\n\t\t\tif postIndex > l {\n\t\t\t\treturn io.ErrUnexpectedEOF\n\t\t\t}\n\t\t\tm.Name = string(dAtA[iNdEx:postIndex])\n\t\t\tiNdEx = postIndex\n\t\tdefault:\n\t\t\tiNdEx = preIndex\n\t\t\tskippy, err := skipMessage(dAtA[iNdEx:])\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tif skippy < 0 {\n\t\t\t\treturn ErrInvalidLengthMessage\n\t\t\t}\n\t\t\tif (iNdEx + skippy) > l {\n\t\t\t\treturn io.ErrUnexpectedEOF\n\t\t\t}\n\t\t\tiNdEx += skippy\n\t\t}\n\t}\n\n\tif iNdEx > l {\n\t\treturn io.ErrUnexpectedEOF\n\t}\n\treturn nil\n}\nfunc (m *UserProtoResponse) Unmarshal(dAtA []byte) error {\n\tl := len(dAtA)\n\tiNdEx := 0\n\tfor iNdEx < l {\n\t\tpreIndex := iNdEx\n\t\tvar wire uint64\n\t\tfor shift := uint(0); ; shift += 7 {\n\t\t\tif shift >= 64 {\n\t\t\t\treturn ErrIntOverflowMessage\n\t\t\t}\n\t\t\tif iNdEx >= l {\n\t\t\t\treturn io.ErrUnexpectedEOF\n\t\t\t}\n\t\t\tb := dAtA[iNdEx]\n\t\t\tiNdEx++\n\t\t\twire |= (uint64(b) & 0x7F) << shift\n\t\t\tif b < 0x80 {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tfieldNum := int32(wire >> 3)\n\t\twireType := int(wire & 0x7)\n\t\tif wireType == 4 {\n\t\t\treturn fmt.Errorf(\"proto: UserProtoResponse: wiretype end group for non-group\")\n\t\t}\n\t\tif fieldNum <= 0 {\n\t\t\treturn fmt.Errorf(\"proto: UserProtoResponse: illegal tag %d (wire type %d)\", fieldNum, wire)\n\t\t}\n\t\tswitch fieldNum {\n\t\tcase 1:\n\t\t\tif wireType != 0 {\n\t\t\t\treturn fmt.Errorf(\"proto: wrong wireType = %d for field Id\", wireType)\n\t\t\t}\n\t\t\tm.Id = 0\n\t\t\tfor shift := uint(0); ; shift += 7 {\n\t\t\t\tif shift >= 64 {\n\t\t\t\t\treturn ErrIntOverflowMessage\n\t\t\t\t}\n\t\t\t\tif iNdEx >= l {\n\t\t\t\t\treturn io.ErrUnexpectedEOF\n\t\t\t\t}\n\t\t\t\tb := dAtA[iNdEx]\n\t\t\t\tiNdEx++\n\t\t\t\tm.Id |= (int32(b) & 0x7F) << shift\n\t\t\t\tif b < 0x80 {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\tcase 2:\n\t\t\tif wireType != 2 {\n\t\t\t\treturn fmt.Errorf(\"proto: wrong wireType = %d for field Name\", wireType)\n\t\t\t}\n\t\t\tvar stringLen uint64\n\t\t\tfor shift := uint(0); ; shift += 7 {\n\t\t\t\tif shift >= 64 {\n\t\t\t\t\treturn ErrIntOverflowMessage\n\t\t\t\t}\n\t\t\t\tif iNdEx >= l {\n\t\t\t\t\treturn io.ErrUnexpectedEOF\n\t\t\t\t}\n\t\t\t\tb := dAtA[iNdEx]\n\t\t\t\tiNdEx++\n\t\t\t\tstringLen |= (uint64(b) & 0x7F) << shift\n\t\t\t\tif b < 0x80 {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tintStringLen := int(stringLen)\n\t\t\tif intStringLen < 0 {\n\t\t\t\treturn ErrInvalidLengthMessage\n\t\t\t}\n\t\t\tpostIndex := iNdEx + intStringLen\n\t\t\tif postIndex > l {\n\t\t\t\treturn io.ErrUnexpectedEOF\n\t\t\t}\n\t\t\tm.Name = string(dAtA[iNdEx:postIndex])\n\t\t\tiNdEx = postIndex\n\t\tcase 3:\n\t\t\tif wireType != 0 {\n\t\t\t\treturn fmt.Errorf(\"proto: wrong wireType = %d for field Active\", wireType)\n\t\t\t}\n\t\t\tvar v int\n\t\t\tfor shift := uint(0); ; shift += 7 {\n\t\t\t\tif shift >= 64 {\n\t\t\t\t\treturn ErrIntOverflowMessage\n\t\t\t\t}\n\t\t\t\tif iNdEx >= l {\n\t\t\t\t\treturn io.ErrUnexpectedEOF\n\t\t\t\t}\n\t\t\t\tb := dAtA[iNdEx]\n\t\t\t\tiNdEx++\n\t\t\t\tv |= (int(b) & 0x7F) << shift\n\t\t\t\tif b < 0x80 {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tm.Active = bool(v != 0)\n\t\tcase 4:\n\t\t\tif wireType != 2 {\n\t\t\t\treturn fmt.Errorf(\"proto: wrong wireType = %d for field Setting\", wireType)\n\t\t\t}\n\t\t\tvar msglen int\n\t\t\tfor shift := uint(0); ; shift += 7 {\n\t\t\t\tif shift >= 64 {\n\t\t\t\t\treturn ErrIntOverflowMessage\n\t\t\t\t}\n\t\t\t\tif iNdEx >= l {\n\t\t\t\t\treturn io.ErrUnexpectedEOF\n\t\t\t\t}\n\t\t\t\tb := dAtA[iNdEx]\n\t\t\t\tiNdEx++\n\t\t\t\tmsglen |= (int(b) & 0x7F) << shift\n\t\t\t\tif b < 0x80 {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tif msglen < 0 {\n\t\t\t\treturn ErrInvalidLengthMessage\n\t\t\t}\n\t\t\tpostIndex := iNdEx + msglen\n\t\t\tif postIndex > l {\n\t\t\t\treturn io.ErrUnexpectedEOF\n\t\t\t}\n\t\t\tif m.Setting == nil {\n\t\t\t\tm.Setting = &UserProtoResponse_Setting{}\n\t\t\t}\n\t\t\tif err := m.Setting.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tiNdEx = postIndex\n\t\tdefault:\n\t\t\tiNdEx = preIndex\n\t\t\tskippy, err := skipMessage(dAtA[iNdEx:])\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tif skippy < 0 {\n\t\t\t\treturn ErrInvalidLengthMessage\n\t\t\t}\n\t\t\tif (iNdEx + skippy) > l {\n\t\t\t\treturn io.ErrUnexpectedEOF\n\t\t\t}\n\t\t\tiNdEx += skippy\n\t\t}\n\t}\n\n\tif iNdEx > l {\n\t\treturn io.ErrUnexpectedEOF\n\t}\n\treturn nil\n}\nfunc (m *UserProtoResponse_Setting) Unmarshal(dAtA []byte) error {\n\tl := len(dAtA)\n\tiNdEx := 0\n\tfor iNdEx < l {\n\t\tpreIndex := iNdEx\n\t\tvar wire uint64\n\t\tfor shift := uint(0); ; shift += 7 {\n\t\t\tif shift >= 64 {\n\t\t\t\treturn ErrIntOverflowMessage\n\t\t\t}\n\t\t\tif iNdEx >= l {\n\t\t\t\treturn io.ErrUnexpectedEOF\n\t\t\t}\n\t\t\tb := dAtA[iNdEx]\n\t\t\tiNdEx++\n\t\t\twire |= (uint64(b) & 0x7F) << shift\n\t\t\tif b < 0x80 {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tfieldNum := int32(wire >> 3)\n\t\twireType := int(wire & 0x7)\n\t\tif wireType == 4 {\n\t\t\treturn fmt.Errorf(\"proto: Setting: wiretype end group for non-group\")\n\t\t}\n\t\tif fieldNum <= 0 {\n\t\t\treturn fmt.Errorf(\"proto: Setting: illegal tag %d (wire type %d)\", fieldNum, wire)\n\t\t}\n\t\tswitch fieldNum {\n\t\tcase 1:\n\t\t\tif wireType != 2 {\n\t\t\t\treturn fmt.Errorf(\"proto: wrong wireType = %d for field Email\", wireType)\n\t\t\t}\n\t\t\tvar stringLen uint64\n\t\t\tfor shift := uint(0); ; shift += 7 {\n\t\t\t\tif shift >= 64 {\n\t\t\t\t\treturn ErrIntOverflowMessage\n\t\t\t\t}\n\t\t\t\tif iNdEx >= l {\n\t\t\t\t\treturn io.ErrUnexpectedEOF\n\t\t\t\t}\n\t\t\t\tb := dAtA[iNdEx]\n\t\t\t\tiNdEx++\n\t\t\t\tstringLen |= (uint64(b) & 0x7F) << shift\n\t\t\t\tif b < 0x80 {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tintStringLen := int(stringLen)\n\t\t\tif intStringLen < 0 {\n\t\t\t\treturn ErrInvalidLengthMessage\n\t\t\t}\n\t\t\tpostIndex := iNdEx + intStringLen\n\t\t\tif postIndex > l {\n\t\t\t\treturn io.ErrUnexpectedEOF\n\t\t\t}\n\t\t\tm.Email = string(dAtA[iNdEx:postIndex])\n\t\t\tiNdEx = postIndex\n\t\tdefault:\n\t\t\tiNdEx = preIndex\n\t\t\tskippy, err := skipMessage(dAtA[iNdEx:])\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tif skippy < 0 {\n\t\t\t\treturn ErrInvalidLengthMessage\n\t\t\t}\n\t\t\tif (iNdEx + skippy) > l {\n\t\t\t\treturn io.ErrUnexpectedEOF\n\t\t\t}\n\t\t\tiNdEx += skippy\n\t\t}\n\t}\n\n\tif iNdEx > l {\n\t\treturn io.ErrUnexpectedEOF\n\t}\n\treturn nil\n}\nfunc skipMessage(dAtA []byte) (n int, err error) {\n\tl := len(dAtA)\n\tiNdEx := 0\n\tfor iNdEx < l {\n\t\tvar wire uint64\n\t\tfor shift := uint(0); ; shift += 7 {\n\t\t\tif shift >= 64 {\n\t\t\t\treturn 0, ErrIntOverflowMessage\n\t\t\t}\n\t\t\tif iNdEx >= l {\n\t\t\t\treturn 0, io.ErrUnexpectedEOF\n\t\t\t}\n\t\t\tb := dAtA[iNdEx]\n\t\t\tiNdEx++\n\t\t\twire |= (uint64(b) & 0x7F) << shift\n\t\t\tif b < 0x80 {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\twireType := int(wire & 0x7)\n\t\tswitch wireType {\n\t\tcase 0:\n\t\t\tfor shift := uint(0); ; shift += 7 {\n\t\t\t\tif shift >= 64 {\n\t\t\t\t\treturn 0, ErrIntOverflowMessage\n\t\t\t\t}\n\t\t\t\tif iNdEx >= l {\n\t\t\t\t\treturn 0, io.ErrUnexpectedEOF\n\t\t\t\t}\n\t\t\t\tiNdEx++\n\t\t\t\tif dAtA[iNdEx-1] < 0x80 {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn iNdEx, nil\n\t\tcase 1:\n\t\t\tiNdEx += 8\n\t\t\treturn iNdEx, nil\n\t\tcase 2:\n\t\t\tvar length int\n\t\t\tfor shift := uint(0); ; shift += 7 {\n\t\t\t\tif shift >= 64 {\n\t\t\t\t\treturn 0, ErrIntOverflowMessage\n\t\t\t\t}\n\t\t\t\tif iNdEx >= l {\n\t\t\t\t\treturn 0, io.ErrUnexpectedEOF\n\t\t\t\t}\n\t\t\t\tb := dAtA[iNdEx]\n\t\t\t\tiNdEx++\n\t\t\t\tlength |= (int(b) & 0x7F) << shift\n\t\t\t\tif b < 0x80 {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tiNdEx += length\n\t\t\tif length < 0 {\n\t\t\t\treturn 0, ErrInvalidLengthMessage\n\t\t\t}\n\t\t\treturn iNdEx, nil\n\t\tcase 3:\n\t\t\tfor {\n\t\t\t\tvar innerWire uint64\n\t\t\t\tvar start int = iNdEx\n\t\t\t\tfor shift := uint(0); ; shift += 7 {\n\t\t\t\t\tif shift >= 64 {\n\t\t\t\t\t\treturn 0, ErrIntOverflowMessage\n\t\t\t\t\t}\n\t\t\t\t\tif iNdEx >= l {\n\t\t\t\t\t\treturn 0, io.ErrUnexpectedEOF\n\t\t\t\t\t}\n\t\t\t\t\tb := dAtA[iNdEx]\n\t\t\t\t\tiNdEx++\n\t\t\t\t\tinnerWire |= (uint64(b) & 0x7F) << shift\n\t\t\t\t\tif b < 0x80 {\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tinnerWireType := int(innerWire & 0x7)\n\t\t\t\tif innerWireType == 4 {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tnext, err := skipMessage(dAtA[start:])\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn 0, err\n\t\t\t\t}\n\t\t\t\tiNdEx = start + next\n\t\t\t}\n\t\t\treturn iNdEx, nil\n\t\tcase 4:\n\t\t\treturn iNdEx, nil\n\t\tcase 5:\n\t\t\tiNdEx += 4\n\t\t\treturn iNdEx, nil\n\t\tdefault:\n\t\t\treturn 0, fmt.Errorf(\"proto: illegal wireType %d\", wireType)\n\t\t}\n\t}\n\tpanic(\"unreachable\")\n}\n\nvar (\n\tErrInvalidLengthMessage = fmt.Errorf(\"proto: negative length found during unmarshaling\")\n\tErrIntOverflowMessage   = fmt.Errorf(\"proto: integer overflow\")\n)\n\nfunc init() { proto.RegisterFile(\"message.proto\", fileDescriptorMessage) }\n\nvar fileDescriptorMessage = []byte{\n\t// 211 bytes of a gzipped FileDescriptorProto\n\t0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0xcd, 0x4d, 0x2d, 0x2e,\n\t0x4e, 0x4c, 0x4f, 0xd5, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0xcf, 0x28, 0x29, 0x29, 0x48,\n\t0xc9, 0x4f, 0x56, 0x32, 0xe3, 0x12, 0x08, 0x2d, 0x4e, 0x2d, 0x0a, 0x00, 0x89, 0x06, 0xa5, 0x16,\n\t0x96, 0xa6, 0x16, 0x97, 0x08, 0xf1, 0x71, 0x31, 0x65, 0xa6, 0x48, 0x30, 0x2a, 0x30, 0x6a, 0xb0,\n\t0x06, 0x31, 0x65, 0xa6, 0x08, 0x09, 0x71, 0xb1, 0xe4, 0x25, 0xe6, 0xa6, 0x4a, 0x30, 0x29, 0x30,\n\t0x6a, 0x70, 0x06, 0x81, 0xd9, 0x4a, 0xeb, 0x18, 0xb9, 0x04, 0x91, 0x34, 0x16, 0x17, 0xe4, 0xe7,\n\t0x15, 0xa7, 0x12, 0xa3, 0x53, 0x48, 0x8c, 0x8b, 0x2d, 0x31, 0xb9, 0x24, 0xb3, 0x2c, 0x55, 0x82,\n\t0x59, 0x81, 0x51, 0x83, 0x23, 0x08, 0xca, 0x13, 0xb2, 0xe1, 0x62, 0x2f, 0x4e, 0x2d, 0x29, 0xc9,\n\t0xcc, 0x4b, 0x97, 0x60, 0x51, 0x60, 0xd4, 0xe0, 0x36, 0x52, 0xd2, 0x83, 0x3a, 0x52, 0x0f, 0xc3,\n\t0x22, 0xbd, 0x60, 0x88, 0xca, 0x20, 0x98, 0x16, 0x29, 0x79, 0x2e, 0x76, 0xa8, 0x98, 0x90, 0x08,\n\t0x17, 0x6b, 0x6a, 0x6e, 0x62, 0x66, 0x0e, 0xd8, 0x1d, 0x9c, 0x41, 0x10, 0x8e, 0x93, 0xc0, 0x89,\n\t0x47, 0x72, 0x8c, 0x17, 0x1e, 0xc9, 0x31, 0x3e, 0x78, 0x24, 0xc7, 0x38, 0xe3, 0xb1, 0x1c, 0x43,\n\t0x12, 0x1b, 0x38, 0x28, 0x8c, 0x01, 0x01, 0x00, 0x00, 0xff, 0xff, 0xc5, 0x23, 0xb1, 0xd2, 0x1b,\n\t0x01, 0x00, 0x00,\n}\n"
  },
  {
    "path": "proto/message.proto",
    "content": "syntax = \"proto3\";\n\npackage httpdoc;\n\nmessage UserProtoRequest {\n  int32 id = 1;\n  string name = 2;\n}\n\nmessage UserProtoResponse {\n  message Setting {\n    string email = 1;\n  }\n  \n  int32 id = 1;\n  string name = 2;\n  bool active = 3;\n  Setting setting = 4;\n}\n"
  },
  {
    "path": "static/bindata.go",
    "content": "// Code generated by go-bindata.\n// sources:\n// tmpl/api-blueprint.tmpl\n// tmpl/doc.md.tmpl\n// DO NOT EDIT!\n\npackage static\n\nimport (\n\t\"bytes\"\n\t\"compress/gzip\"\n\t\"fmt\"\n\t\"io\"\n\t\"io/ioutil\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"time\"\n)\n\nfunc bindataRead(data []byte, name string) ([]byte, error) {\n\tgz, err := gzip.NewReader(bytes.NewBuffer(data))\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"Read %q: %v\", name, err)\n\t}\n\n\tvar buf bytes.Buffer\n\t_, err = io.Copy(&buf, gz)\n\tclErr := gz.Close()\n\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"Read %q: %v\", name, err)\n\t}\n\tif clErr != nil {\n\t\treturn nil, err\n\t}\n\n\treturn buf.Bytes(), nil\n}\n\ntype asset struct {\n\tbytes []byte\n\tinfo  os.FileInfo\n}\n\ntype bindataFileInfo struct {\n\tname    string\n\tsize    int64\n\tmode    os.FileMode\n\tmodTime time.Time\n}\n\nfunc (fi bindataFileInfo) Name() string {\n\treturn fi.name\n}\nfunc (fi bindataFileInfo) Size() int64 {\n\treturn fi.size\n}\nfunc (fi bindataFileInfo) Mode() os.FileMode {\n\treturn fi.mode\n}\nfunc (fi bindataFileInfo) ModTime() time.Time {\n\treturn fi.modTime\n}\nfunc (fi bindataFileInfo) IsDir() bool {\n\treturn false\n}\nfunc (fi bindataFileInfo) Sys() interface{} {\n\treturn nil\n}\n\nvar _tmplApiBlueprintTmpl = []byte(\"\\x1f\\x8b\\x08\\x00\\x00\\x00\\x00\\x00\\x00\\xff\\xac\\x90\\x3d\\x4f\\xc3\\x30\\x10\\x86\\xf7\\xfc\\x8a\\x93\\xb2\\xb4\\xaa\\x1a\\x76\\x36\\x3e\\x8a\\x60\\x00\\x55\\x20\\xb1\\x1f\\xf5\\x4b\\x31\\x4a\\x6c\\x63\\x3b\\x12\\x28\\xca\\x7f\\x47\\x89\\xdd\\xc6\\x4d\\xca\\xc7\\xd0\\x2d\\xe7\\x3c\\xf7\\xde\\x73\\x97\\xd3\\xc5\\xfa\\x2e\\xcb\\xf2\\x9c\\x9a\\x86\\x8a\\x07\\xae\\x40\\x6d\\x9b\\x65\\x4d\\x43\\x96\\xd5\\x16\\x54\\xac\\x94\\xb7\\x12\\x8e\\x96\\xdd\\x73\\x1e\\xb9\\x6b\\xb8\\x8d\\x95\\xc6\\x4b\\xad\\xa8\\x6d\\xfb\\xa7\\x7b\\xf8\\x37\\x2d\\x76\\xcd\\xf2\\x95\\x8a\\x47\\x7c\\xd4\\x70\\xfe\\x46\\xa2\\x14\\xa1\\x7f\\x48\\x9d\\xfe\\x5b\\xa4\\x02\\x34\\x73\\xde\\x4a\\xb5\\x9d\\xd3\\xf2\\xc8\\xbc\\x2e\\x07\\x4a\\x1c\\x7e\\x8d\\xa6\\xae\\xd9\\x72\\xb5\\x4b\\xee\\x0b\\x78\\x58\\x37\\x55\\x48\\x40\\xa2\\x91\\x84\\xaa\\xab\\x17\\xd8\\xbf\\x24\\x12\\x87\\x05\\xc5\\x54\\x9a\\xb1\\x31\\xa5\\xdc\\x70\\x47\\x9f\\xbd\\x3b\\xad\\xe6\\x23\\xc1\\x5b\\xb0\\x80\\x1d\\x06\\xc7\\x7a\\x2a\\x78\\x08\\x52\\x6a\\x78\\xde\\x17\\xcf\\x5c\\xd6\\xf8\\xe9\\x2c\\x5d\\xf4\\xa5\\x16\\x5f\\xfb\\xd6\\x98\\xba\\xfa\\xe4\\xca\\x94\\xd8\\x5b\\x3b\\xa3\\x95\\x43\\x24\\x42\\xf1\\xe4\\xd9\\xd7\\xee\\x4a\\x8b\\x70\\x8c\\x5f\\x16\\x0a\\xfc\\x7f\\x36\\x3a\\x46\\x9e\\x60\\xa5\\x10\\x9b\\xee\\x34\\xe0\\xdf\\x01\\x00\\x00\\xff\\xff\\x6d\\xf2\\xb7\\x0d\\xe2\\x02\\x00\\x00\")\n\nfunc tmplApiBlueprintTmplBytes() ([]byte, error) {\n\treturn bindataRead(\n\t\t_tmplApiBlueprintTmpl,\n\t\t\"tmpl/api-blueprint.tmpl\",\n\t)\n}\n\nfunc tmplApiBlueprintTmpl() (*asset, error) {\n\tbytes, err := tmplApiBlueprintTmplBytes()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tinfo := bindataFileInfo{name: \"tmpl/api-blueprint.tmpl\", size: 738, mode: os.FileMode(420), modTime: time.Unix(1496893135, 0)}\n\ta := &asset{bytes: bytes, info: info}\n\treturn a, nil\n}\n\nvar _tmplDocMdTmpl = []byte(\"\\x1f\\x8b\\x08\\x00\\x00\\x00\\x00\\x00\\x00\\xff\\xb4\\x53\\xc1\\x6e\\xd4\\x30\\x10\\xbd\\xcf\\x57\\x8c\\x94\\x03\\x70\\xd8\\xf4\\x8e\\x56\\x95\\x50\\x5b\\x04\\x07\\xd0\\xaa\\x54\\x5c\\x2a\\xa4\\x4c\\xe3\\xd9\\xc6\\x90\\xd8\\xc1\\x9e\\x40\\xab\\x4d\\xfe\\x1d\\xd9\\xde\\xad\\x1c\\x6d\\xf7\\x42\\x9b\\x9c\\x66\\x9e\\xc7\\xf3\\xde\\x9b\\x8c\\x0b\\xfc\\xb0\\xf9\\x8c\\xca\\xd6\\x00\\x37\\x8d\\xf6\\xa8\\xfd\\x01\\x18\\x3a\\x36\\x42\\xa2\\xad\\xc1\\xad\\x75\\xb8\\xdb\\x61\\xf9\\x95\\x3a\\xc6\\x69\\x2a\\xf1\\x50\\x7a\\xcf\\x86\\x1d\\x09\\x2b\\xbc\\x7b\\xc4\\xaa\\x11\\xe9\\x95\\xad\\xab\\x12\\x2f\\xad\\x79\\x23\\xc8\\x4a\\x4b\\x38\\x68\\xc8\\xa8\\x12\\xa0\\x28\\xf0\\x86\\xee\\x5a\\x46\\xbb\\xc5\\xda\\x1a\\x61\\x23\\x1e\\x60\\xb7\\x43\\x47\\xe6\\x9e\\xb1\\xbc\\x32\\xe2\\x34\\x7b\\x5c\\x4d\\x13\\xac\\xf0\\xf6\\x36\\x30\\x5e\\xb3\\xef\\xad\\xf1\\xfc\\x4d\\x48\\x06\\x7f\\x61\\x55\\xe0\\xff\\x11\\xc5\\x7c\\x61\\x69\\xac\\xc2\\x69\\x8a\\xd9\\x86\\xa4\\x09\\x47\\x6f\\x8b\\x93\\xd7\\x56\\xd9\\xad\\x11\\x5b\\xfb\\x97\\xdd\\x01\\x8d\\xb7\\x47\\xf4\\xe2\\x74\\xef\\x5b\\xf2\\x4d\\x56\\xf0\\x2e\\x48\\x64\\x13\\x98\\x4e\\xa9\\x2d\\x0a\\xfc\\x2f\\xb5\\xb1\\x5f\\x79\\xc9\\xbe\\x76\\xba\\x8f\\x93\\x0e\\x58\\x51\\x14\\x78\\xcd\\xbf\\x07\\xf6\\x12\\x0b\\xf4\\x36\\x74\\x8e\\xf9\\x86\\x1c\\x75\\x89\\x33\\x86\\x2c\\xec\\x3c\\xc0\\x88\\xf1\\xcf\\xe0\\x88\\xdf\\xa9\\x1d\\x62\\x90\\x37\\x1d\\x61\\xc4\\x55\\xf8\\x70\\xc4\\xf7\\xf3\\x20\\x25\\x99\\xad\\x63\\xa2\\x31\\xff\\xf5\\x98\\xb2\\x44\\xf3\\x94\\xce\\x1d\\xa4\\x7e\\x69\\x62\\xf3\\xd1\\x65\\x4e\\x3e\\x31\\x29\\x76\\x89\\x61\\x1f\\x2f\\xe1\\x23\\xa7\\x79\\x91\\x11\\x38\\xe9\\xe4\\xa3\\xe6\\x56\\x25\\x86\\x3d\\x82\\xdb\\x08\\x2d\\xe1\\x27\\x23\\x5b\\xc8\\xce\\xd5\\x03\\x75\\x7d\\xcb\\x33\\x3f\\x9c\\x30\\x80\\xb5\\x62\\x21\\xdd\\xfa\\x73\\x58\\xfb\\xa1\\xeb\\xc8\\x3d\\x9e\\x5f\\xb4\\xba\\xfe\\x85\\x62\\x91\\x1f\\x7a\\x32\\x0a\\x6b\\xab\\xb8\\x5c\\x9f\\x1d\\x8e\\x01\\xaa\\xaa\\xfa\\x49\\x7f\\x28\\x29\\x81\\xf4\\x4c\\x66\\x4c\\xd3\\x14\\x6a\\x00\\xd6\\x67\\x4f\\xdd\\x33\\x75\\xe9\\x35\\xa4\\x77\\x95\\x69\\x4d\\xc0\\xf2\\x5b\\x74\\xcc\\xf3\\xfa\\x73\\x4f\\x1c\\xb3\\x3d\\x4a\\xd0\\x32\\x8b\\x74\\x44\\xb7\\x94\\xa3\\xf9\\x2a\\xed\\x2d\\xbd\\xfa\\x2e\\xcd\\xb9\\x9e\\x59\\xa6\\x67\\xb5\\xfe\\x0b\\x00\\x00\\xff\\xff\\x2f\\x57\\xc7\\x87\\xf8\\x06\\x00\\x00\")\n\nfunc tmplDocMdTmplBytes() ([]byte, error) {\n\treturn bindataRead(\n\t\t_tmplDocMdTmpl,\n\t\t\"tmpl/doc.md.tmpl\",\n\t)\n}\n\nfunc tmplDocMdTmpl() (*asset, error) {\n\tbytes, err := tmplDocMdTmplBytes()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tinfo := bindataFileInfo{name: \"tmpl/doc.md.tmpl\", size: 1784, mode: os.FileMode(420), modTime: time.Unix(1496894277, 0)}\n\ta := &asset{bytes: bytes, info: info}\n\treturn a, nil\n}\n\n// Asset loads and returns the asset for the given name.\n// It returns an error if the asset could not be found or\n// could not be loaded.\nfunc Asset(name string) ([]byte, error) {\n\tcannonicalName := strings.Replace(name, \"\\\\\", \"/\", -1)\n\tif f, ok := _bindata[cannonicalName]; ok {\n\t\ta, err := f()\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"Asset %s can't read by error: %v\", name, err)\n\t\t}\n\t\treturn a.bytes, nil\n\t}\n\treturn nil, fmt.Errorf(\"Asset %s not found\", name)\n}\n\n// MustAsset is like Asset but panics when Asset would return an error.\n// It simplifies safe initialization of global variables.\nfunc MustAsset(name string) []byte {\n\ta, err := Asset(name)\n\tif err != nil {\n\t\tpanic(\"asset: Asset(\" + name + \"): \" + err.Error())\n\t}\n\n\treturn a\n}\n\n// AssetInfo loads and returns the asset info for the given name.\n// It returns an error if the asset could not be found or\n// could not be loaded.\nfunc AssetInfo(name string) (os.FileInfo, error) {\n\tcannonicalName := strings.Replace(name, \"\\\\\", \"/\", -1)\n\tif f, ok := _bindata[cannonicalName]; ok {\n\t\ta, err := f()\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"AssetInfo %s can't read by error: %v\", name, err)\n\t\t}\n\t\treturn a.info, nil\n\t}\n\treturn nil, fmt.Errorf(\"AssetInfo %s not found\", name)\n}\n\n// AssetNames returns the names of the assets.\nfunc AssetNames() []string {\n\tnames := make([]string, 0, len(_bindata))\n\tfor name := range _bindata {\n\t\tnames = append(names, name)\n\t}\n\treturn names\n}\n\n// _bindata is a table, holding each asset generator, mapped to its name.\nvar _bindata = map[string]func() (*asset, error){\n\t\"tmpl/api-blueprint.tmpl\": tmplApiBlueprintTmpl,\n\t\"tmpl/doc.md.tmpl\": tmplDocMdTmpl,\n}\n\n// AssetDir returns the file names below a certain\n// directory embedded in the file by go-bindata.\n// For example if you run go-bindata on data/... and data contains the\n// following hierarchy:\n//     data/\n//       foo.txt\n//       img/\n//         a.png\n//         b.png\n// then AssetDir(\"data\") would return []string{\"foo.txt\", \"img\"}\n// AssetDir(\"data/img\") would return []string{\"a.png\", \"b.png\"}\n// AssetDir(\"foo.txt\") and AssetDir(\"notexist\") would return an error\n// AssetDir(\"\") will return []string{\"data\"}.\nfunc AssetDir(name string) ([]string, error) {\n\tnode := _bintree\n\tif len(name) != 0 {\n\t\tcannonicalName := strings.Replace(name, \"\\\\\", \"/\", -1)\n\t\tpathList := strings.Split(cannonicalName, \"/\")\n\t\tfor _, p := range pathList {\n\t\t\tnode = node.Children[p]\n\t\t\tif node == nil {\n\t\t\t\treturn nil, fmt.Errorf(\"Asset %s not found\", name)\n\t\t\t}\n\t\t}\n\t}\n\tif node.Func != nil {\n\t\treturn nil, fmt.Errorf(\"Asset %s not found\", name)\n\t}\n\trv := make([]string, 0, len(node.Children))\n\tfor childName := range node.Children {\n\t\trv = append(rv, childName)\n\t}\n\treturn rv, nil\n}\n\ntype bintree struct {\n\tFunc     func() (*asset, error)\n\tChildren map[string]*bintree\n}\nvar _bintree = &bintree{nil, map[string]*bintree{\n\t\"tmpl\": &bintree{nil, map[string]*bintree{\n\t\t\"api-blueprint.tmpl\": &bintree{tmplApiBlueprintTmpl, map[string]*bintree{}},\n\t\t\"doc.md.tmpl\": &bintree{tmplDocMdTmpl, map[string]*bintree{}},\n\t}},\n}}\n\n// RestoreAsset restores an asset under the given directory\nfunc RestoreAsset(dir, name string) error {\n\tdata, err := Asset(name)\n\tif err != nil {\n\t\treturn err\n\t}\n\tinfo, err := AssetInfo(name)\n\tif err != nil {\n\t\treturn err\n\t}\n\terr = os.MkdirAll(_filePath(dir, filepath.Dir(name)), os.FileMode(0755))\n\tif err != nil {\n\t\treturn err\n\t}\n\terr = ioutil.WriteFile(_filePath(dir, name), data, info.Mode())\n\tif err != nil {\n\t\treturn err\n\t}\n\terr = os.Chtimes(_filePath(dir, name), info.ModTime(), info.ModTime())\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\n// RestoreAssets restores an asset under the given directory recursively\nfunc RestoreAssets(dir, name string) error {\n\tchildren, err := AssetDir(name)\n\t// File\n\tif err != nil {\n\t\treturn RestoreAsset(dir, name)\n\t}\n\t// Dir\n\tfor _, child := range children {\n\t\terr = RestoreAssets(dir, filepath.Join(name, child))\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc _filePath(dir, name string) string {\n\tcannonicalName := strings.Replace(name, \"\\\\\", \"/\", -1)\n\treturn filepath.Join(append([]string{dir}, strings.Split(cannonicalName, \"/\")...)...)\n}\n\n"
  },
  {
    "path": "static/static.go",
    "content": "package static\n\n//go:generate go-bindata -pkg=static ./tmpl/...\n"
  },
  {
    "path": "static/tmpl/doc.md.tmpl",
    "content": "# API doc\n\nThis is API documentation for {{ .Name }}. This is generated by `httpdoc`. Don't edit by hand.\n\n## Table of contents\n\n{{ range .Entries -}}\n- [[{{ .ResponseStatusCode }}] {{ .Method }} {{ .Path }}](#{{ .ResponseStatusCode }}-{{ .Method | lower }}-{{ .Path | stripslash | lower }})\n{{ end }}\n\n{{ range .Entries -}}\n## [{{ .ResponseStatusCode }}] {{ .Method }} {{ .Path }}\n\n{{ .Description }}\n\n### Request\n\n{{ if .RequestParams -}}\nParameters\n\n| Name  | Value  | Description |\n| ----- | :----- | :--------- |\n{{ range .RequestParams -}}\n| {{ .Name }} | {{ .Value }} | {{ .Description }} |\n{{ end }}{{ end }}\n\n{{ if .RequestHeaders -}}\nHeaders\n\n| Name  | Value  | Description |\n| ----- | :----- | :--------- |\n{{ range .RequestHeaders -}}\n| {{ .Name }} | {{ .Value }} | {{ .Description }} |\n{{ end }}\n{{ end }}\n\n{{ if .RequestFields -}}\nRequest fields\n\n| Name  | Value  | Description |\n| ----- | :----- | :--------- |\n{{ range .RequestFields -}}\n| {{ .Name }} | {{ .Value }} | {{ .Description }} |\n{{ end }}\n{{ end }}\n\n{{ if .RequestExample -}}\nRequest example\n\n<details>\n<summary>Click to expand code.</summary>\n\n```javascript\n{{ .RequestExample }}\n```\n\n</details>\n{{ end }}\n\n### Response\n\n{{ if .ResponseHeaders -}}\nHeaders\n\n| Name  | Value  | Description |\n| ----- | :----- | :--------- |\n{{ range .ResponseHeaders -}}\n| {{ .Name }} | {{ .Value }} | {{ .Description }} |\n{{ end }}\n{{ end }}\n\n{{ if .ResponseFields -}}\nResponse fields\n\n| Name  | Value  | Description |\n| ----- | :----- | :--------- |\n{{ range .ResponseFields -}}\n| {{ .Name }} | {{ .Value }} | {{ .Description }} |\n{{ end }}\n{{ end }}\n\n{{ if .ResponseExample -}}\nResponse example\n\n<details>\n<summary>Click to expand code.</summary>\n\n```javascript\n{{ .ResponseExample }}\n```\n\n</details>\n\n{{ end }}\n{{ end }}\n"
  },
  {
    "path": "template.go",
    "content": "package httpdoc\n\nimport (\n\t\"io\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"text/template\"\n\n\t\"go.mercari.io/go-httpdoc/static\"\n)\n\n// defaultTmpl is default template file to use.\nvar defaultTmpl = \"tmpl/doc.md.tmpl\"\n\n// Generate writes documentation into the given file. Generation is skipped\n// if EnvHTTPDoc is empty. If directory does not exist or any, it returns error.\nfunc (d *Document) Generate(path string) error {\n\n\t// Only generate documentation when EnvHttpDoc has non-empty value\n\tif os.Getenv(EnvHTTPDoc) == \"\" {\n\t\treturn nil\n\t}\n\n\tpath, _ = filepath.Abs(path)\n\tif _, err := os.Stat(filepath.Dir(path)); err != nil && os.IsNotExist(err) {\n\t\tif err := os.MkdirAll(filepath.Dir(path), 0700); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tf, err := os.Create(path)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn d.generate(f)\n}\n\nfunc (d *Document) generate(w io.Writer) error {\n\tif d.tmpl == \"\" {\n\t\td.tmpl = defaultTmpl\n\t}\n\n\tbuf, err := static.Asset(d.tmpl)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn d.tmplExecute(w, string(buf))\n}\n\nfunc (d *Document) tmplExecute(w io.Writer, text string) error {\n\ttmpl, err := template.New(\"httpdoc\").Funcs(funcMap()).Parse(text)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif err := tmpl.Execute(w, d); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc funcMap() template.FuncMap {\n\treturn template.FuncMap{\n\t\t\"lower\": strings.ToLower,\n\t\t\"stripslash\": func(s string) string {\n\t\t\treturn strings.Replace(s, \"/\", \"\", -1)\n\t\t},\n\t}\n}\n"
  },
  {
    "path": "template_test.go",
    "content": "package httpdoc\n\nimport (\n\t\"io/ioutil\"\n\t\"os\"\n\t\"testing\"\n)\n\nfunc setEnv(t *testing.T, k, v string) func() {\n\tpreV := os.Getenv(k)\n\tif err := os.Setenv(k, v); err != nil {\n\t\tt.Fatal(err)\n\t}\n\n\treturn func() {\n\t\tif err := os.Setenv(k, preV); err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t}\n}\n\nfunc TestDocument_Generate(t *testing.T) {\n\tresetF := setEnv(t, EnvHTTPDoc, \"test\")\n\tdefer resetF()\n\n\tf, err := ioutil.TempFile(\"\", \"\")\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\n\tdoc := &Document{}\n\tif err := doc.Generate(f.Name()); err != nil {\n\t\tt.Fatal(err)\n\t}\n\n\tfi, err := os.Stat(f.Name())\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\n\tif fi.Size() == 0 {\n\t\tt.Fatalf(\"expect doc to be generated\")\n\t}\n}\n\nfunc TestDocument_Generate_noEnv(t *testing.T) {\n\tresetF := setEnv(t, EnvHTTPDoc, \"\")\n\tdefer resetF()\n\n\tf, err := ioutil.TempFile(\"\", \"\")\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\n\tdoc := &Document{}\n\tif err := doc.Generate(f.Name()); err != nil {\n\t\tt.Fatal(err)\n\t}\n\n\tfi, err := os.Stat(f.Name())\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\n\tif fi.Size() > 0 {\n\t\tt.Fatalf(\"expect doc not to be generated\")\n\t}\n}\n\nfunc TestFuncMap(t *testing.T) {\n\tm := funcMap()\n\tlower := m[\"lower\"].(func(s string) string)\n\tif got, want := lower(\"DOC\"), \"doc\"; got != want {\n\t\tt.Fatalf(\"got %q, want %q\", got, want)\n\t}\n\n\tstripslash := m[\"stripslash\"].(func(s string) string)\n\tif got, want := stripslash(\"/v2/user/contact\"), \"v2usercontact\"; got != want {\n\t\tt.Fatalf(\"got %q, want %q\", got, want)\n\t}\n}\n\nfunc TestTemplateGenerate_NotExistDir(t *testing.T) {\n\tresetF := setEnv(t, EnvHTTPDoc, \"1\")\n\tdefer resetF()\n\n\tdoc := &Document{}\n\tif err := doc.Generate(\"/tmp/httpdoc/no-such-file-or-directory\"); err != nil {\n\t\tt.Fatalf(\"expect to be failed\")\n\t}\n\tdefer os.RemoveAll(\"/tmp/httpdoc\")\n}\n\nfunc TestTemplateGenerate_InvalidTmpl(t *testing.T) {\n\tdoc := &Document{\n\t\ttmpl: \"no-such-template\",\n\t}\n\tif err := doc.generate(ioutil.Discard); err == nil {\n\t\tt.Fatalf(\"expect to be failed\")\n\t}\n}\n\nfunc TestTmplExecute_InvalidTemplate(t *testing.T) {\n\tcases := []struct {\n\t\ttext string\n\t}{\n\t\t{\n\t\t\t`{{ .Name }`,\n\t\t},\n\t\t{\n\t\t\t`{{ .Name.NoSuchField }}`,\n\t\t},\n\t}\n\n\tdoc := &Document{}\n\tfor _, tc := range cases {\n\t\tif err := doc.tmplExecute(ioutil.Discard, tc.text); err == nil {\n\t\t\tt.Fatalf(\"expect to be failed\")\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "validate.go",
    "content": "package httpdoc\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"reflect\"\n\t\"testing\"\n\n\t\"github.com/golang/protobuf/proto\"\n\t\"github.com/tenntenn/gpath\"\n)\n\nvar (\n\tdefaultUnmarshalFunc = json.Unmarshal\n\n\tdefaultAssertFunc = func(t *testing.T, expected, actual interface{}, desc string) {\n\t\tif !reflect.DeepEqual(expected, actual) {\n\t\t\ttFatalf(t, \"%s: got %#v(%T), want %#v(%T)\", desc, actual, actual, expected, expected)\n\t\t}\n\t}\n\n\tdefaultFatalFunc = func(t *testing.T, format string, args ...interface{}) {\n\t\tt.Fatalf(format, args...)\n\t}\n\n\tprotoUnmarshalFunc = func(data []byte, v interface{}) error {\n\t\tunmashaler, ok := v.(proto.Unmarshaler)\n\t\tif !ok {\n\t\t\treturn fmt.Errorf(\"failed to type assert to Unmashaler: %T must implement proto.Unmarshaler interface\", v)\n\t\t}\n\t\treturn unmashaler.Unmarshal(data)\n\t}\n)\n\nvar tFatalf fatalFunc = defaultFatalFunc\n\ntype (\n\tassertFunc    func(t *testing.T, expected, actual interface{}, desc string)\n\tfatalFunc     func(t *testing.T, format string, args ...interface{})\n\tunmarshalFunc func(data []byte, v interface{}) error\n)\n\n// Validator takes test cases and checks whether recorded values are equal to the given expected values.\n// If not, it fails in the given test context. If ok, it uses the result for documentation.\ntype Validator struct {\n\trecord *record\n\n\tunmarshalFunc unmarshalFunc\n\tassertFunc    assertFunc\n\n\trequestParams  []Data\n\trequestHeaders []Data\n\trequestFields  []Data\n\n\tresponseHeaders []Data\n\tresponseFields  []Data\n}\n\ntype record struct {\n\trequestParams  url.Values\n\trequestHeaders http.Header\n\trequestBody    []byte\n\n\tresponseStatusCode int\n\tresponseHeaders    http.Header\n\tresponseBody       []byte\n}\n\n// TestCase is test case validator uses. Validator inspects and extract request & response value based on\n// Target (e.g, when testing request params, target is parameter name. when testing response\n// body, target is filed name) and asserts with Expected value.\n//\n// TestCase can be used like table-driven way.\n//\n//   validator.RequestParams(t, []httpdoc.TestCase{\n//       NewTestCase(\"token\",\"12345\",\"Request token\"),\n//       NewTestCase(\"pretty\",\"true\",\"Pretty print response message\"),\n//\t })\n//\ntype TestCase struct {\n\tTarget      string\n\tExpected    interface{}\n\tDescription string\n\tAssertFunc  assertFunc\n}\n\n// NewTestCase returns new TestCase.\nfunc NewTestCase(target string, expected interface{}, description string) TestCase {\n\treturn TestCase{Target: target, Expected: expected, Description: description}\n}\n\nfunc newValidator() *Validator {\n\treturn &Validator{\n\t\tunmarshalFunc: defaultUnmarshalFunc,\n\t\tassertFunc:    defaultAssertFunc,\n\t\trecord:        &record{},\n\t}\n}\n\n// ResponseStatusCode validates response status code is expected or not.\nfunc (v *Validator) ResponseStatusCode(t *testing.T, expected int) {\n\tv.assertFunc(t, expected, v.record.responseStatusCode, \"response status code\")\n}\n\n// RequestParams validated request params are expected or not.\nfunc (v *Validator) RequestParams(t *testing.T, cases []TestCase) {\n\tfor _, tc := range cases {\n\t\tdata := Data{\n\t\t\tName:        tc.Target,\n\t\t\tValue:       tc.Expected,\n\t\t\tDescription: tc.Description,\n\t\t}\n\t\tv.requestParams = append(v.requestParams, data)\n\t\tpickAssertFunc(&tc, v)(t, tc.Expected, v.record.requestParams.Get(tc.Target), tc.Description)\n\t}\n}\n\n// RequestHeaders validates request headers are expected or not.\nfunc (v *Validator) RequestHeaders(t *testing.T, cases []TestCase) {\n\tfor _, tc := range cases {\n\t\tdata := Data{\n\t\t\tName:        tc.Target,\n\t\t\tValue:       tc.Expected,\n\t\t\tDescription: tc.Description,\n\t\t}\n\t\tv.requestHeaders = append(v.requestHeaders, data)\n\n\t\tactual := v.record.requestHeaders.Get(tc.Target)\n\t\tif actual == \"\" {\n\t\t\th, ok := v.record.requestHeaders[tc.Target]\n\t\t\tif !ok || len(h) == 0 {\n\t\t\t\ttFatalf(t, \"request header %q is not found\", tc.Target)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tactual = h[0]\n\t\t}\n\n\t\tpickAssertFunc(&tc, v)(t, tc.Expected, actual, tc.Description)\n\t}\n}\n\n// ResponseHeaders validates response headers are expected or not.\nfunc (v *Validator) ResponseHeaders(t *testing.T, cases []TestCase) {\n\tfor _, tc := range cases {\n\t\tdata := Data{\n\t\t\tName:        tc.Target,\n\t\t\tValue:       tc.Expected,\n\t\t\tDescription: tc.Description,\n\t\t}\n\t\tv.responseHeaders = append(v.responseHeaders, data)\n\n\t\tactual := v.record.responseHeaders.Get(tc.Target)\n\t\tif actual == \"\" {\n\t\t\th, ok := v.record.responseHeaders[tc.Target]\n\t\t\tif !ok || len(h) == 0 {\n\t\t\t\ttFatalf(t, \"request header %q is not found\", tc.Target)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tactual = h[0]\n\t\t}\n\t\tpickAssertFunc(&tc, v)(t, tc.Expected, actual, tc.Description)\n\t}\n}\n\n// RequestBody validates request body's fileds are expected or not. The request body\n// is unmarshaled to the given struct. To extract a filed to validate, this uses dot-seprated\n// expression in TestCase.Target. For example, if you want to access `Email` value in the\n// following struct use `Setting.Name` in Target.\n//\n//   type User struct {\n//       Setting Setting\n//   }\n//\n//   type Setting struct {\n//       Email string\n//   }\n//\nfunc (v *Validator) RequestBody(t *testing.T, cases []TestCase, request interface{}) {\n\t// Unmarshal request body into the given struct\n\tif err := v.unmarshalFunc(v.record.requestBody, request); err != nil {\n\t\ttFatalf(t, \"Failed to unmarshal request body: %s\", err)\n\t\treturn\n\t}\n\tv.validateFields(t, cases, request, &v.requestFields)\n}\n\n// ResponseBody validates response body's fields are expected or not. The response body\n// is unmarshaled to the given struct. To extract a filed to validate, this uses dot-seprated\n// expression in TestCase.Target. For example, if you want to access `Email` value in the\n// following struct use `Setting.Name` in Target.\n//\n//   type User struct {\n//       Setting Setting\n//   }\n//\n//   type Setting struct {\n//       Email string\n//   }\n//\nfunc (v *Validator) ResponseBody(t *testing.T, cases []TestCase, response interface{}) {\n\t// Unmarshal request body into the given struct\n\tif err := v.unmarshalFunc(v.record.responseBody, response); err != nil {\n\t\ttFatalf(t, \"Failed to unmarshal response body: %s\", err)\n\t}\n\tv.validateFields(t, cases, response, &v.responseFields)\n}\n\nfunc (vl *Validator) validateFields(t *testing.T, cases []TestCase, v interface{}, fields *[]Data) {\n\tfor _, tc := range cases {\n\t\tdata := Data{\n\t\t\tName:        tc.Target,\n\t\t\tValue:       tc.Expected,\n\t\t\tDescription: tc.Description,\n\t\t}\n\t\t*fields = append(*fields, data)\n\t\tactual, _ := gpath.At(v, tc.Target)\n\t\tpickAssertFunc(&tc, vl)(t, tc.Expected, actual, tc.Description)\n\t}\n}\n\nfunc pickAssertFunc(tc *TestCase, v *Validator) assertFunc {\n\tif tc.AssertFunc != nil {\n\t\treturn tc.AssertFunc\n\t}\n\treturn v.assertFunc\n}\n"
  },
  {
    "path": "validate_test.go",
    "content": "package httpdoc\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"math/rand\"\n\t\"reflect\"\n\t\"strconv\"\n\t\"strings\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/golang/protobuf/proto\"\n)\n\ntype User struct {\n\tID         int            `json:\"id\"`\n\tName       string         `json:\"name\"`\n\tActive     bool           `json:\"active\"`\n\tSetting    *Setting       `json:\"setting\"`\n\tPermission []string       `json:\"permission\"`\n\tPreference map[string]int `json:\"preference\"`\n}\n\ntype Setting struct {\n\tEmail string `json:\"email\"`\n\tSNS   SNS    `json:\"sns\"`\n}\n\ntype SNS struct {\n\tTwitter  string `json:\"twitter\"`\n\tFacebook string `json:\"facebook\"`\n}\n\n// testAssertWithCount returns assertFunc it counts failed test instead of fail.\nfunc testAssertWithCount(fails *int) assertFunc {\n\treturn func(t *testing.T, expected, actual interface{}, desc string) {\n\t\tif !reflect.DeepEqual(expected, actual) {\n\t\t\t*fails++\n\t\t}\n\t}\n}\n\nfunc fprintFatalFunc(w io.Writer) fatalFunc {\n\treturn func(t *testing.T, format string, args ...interface{}) {\n\t\tfmt.Fprintf(w, format, args...)\n\t}\n}\n\nfunc TestValidator_ResponseStatusCode(t *testing.T) {\n\tvalidator := newValidator()\n\n\tvalidator.record.responseStatusCode = 200\n\tvalidator.ResponseStatusCode(t, 200)\n\n\tvalidator.record.responseStatusCode = 500\n\tvalidator.ResponseStatusCode(t, 500)\n\n\tvar got int\n\tvalidator.assertFunc = testAssertWithCount(&got)\n\tvalidator.record.responseStatusCode = 500\n\tvalidator.ResponseStatusCode(t, 200)\n\tif want := 1; got != want {\n\t\tt.Fatalf(\"expect valiate fails %d, got %d\", want, got)\n\t}\n}\n\nfunc TestValidator_RequestParams(t *testing.T) {\n\tvalidator := newValidator()\n\tvalidator.record.requestParams = map[string][]string{\n\t\t\"token\":  []string{\"12345\"},\n\t\t\"pretty\": []string{\"true\"},\n\t\t\"year\":   []string{strconv.Itoa(time.Now().Year())},\n\t}\n\tthisYearcalledAssertFunc := false\n\tvalidator.RequestParams(t, []TestCase{\n\t\tNewTestCase(\"token\", \"12345\", \"\"),\n\t\tNewTestCase(\"pretty\", \"true\", \"\"),\n\t\t{\"year\", \"thisyear\", \"\", func(t *testing.T, expected, actual interface{}, desc string) {\n\t\t\tif expected != \"thisyear\" {\n\t\t\t\tt.Fatal(\"expected is not thisyear\")\n\t\t\t}\n\t\t\tthisYearcalledAssertFunc = true\n\t\t}},\n\t})\n\n\tif thisYearcalledAssertFunc == false {\n\t\tt.Fatal(\"thisYear AssertFunc should be called.\")\n\t}\n\n\tvar got int\n\tvalidator.assertFunc = testAssertWithCount(&got)\n\tvalidator.RequestParams(t, []TestCase{\n\t\tNewTestCase(\"token\", \"8976\", \"\"),\n\t\tNewTestCase(\"pretty\", \"\", \"\"),\n\t\tNewTestCase(\"id\", \"u8988\", \"\"),\n\t})\n\tif want := 3; got != want {\n\t\tt.Fatalf(\"expect valiate fails %d, got %d\", want, got)\n\t}\n}\n\nfunc TestValidator_RequestHeaders(t *testing.T) {\n\tvalidator := newValidator()\n\tvalidator.record.requestHeaders = map[string][]string{\n\t\t\"User-Agent\":    []string{\"Googlebot/2.1\"},\n\t\t\"Content-Type\":  []string{\"application/json\"},\n\t\t\"X-API-Version\": []string{\"1.1.2\"},\n\t}\n\tvalidator.RequestHeaders(t, []TestCase{\n\t\tNewTestCase(\"User-Agent\", \"Googlebot/2.1\", \"\"),\n\t\tNewTestCase(\"Content-Type\", \"application/json\", \"\"),\n\t\tNewTestCase(\"X-API-Version\", \"1.1.2\", \"\"),\n\t})\n\n\tvar got int\n\tvalidator.assertFunc = testAssertWithCount(&got)\n\tvalidator.RequestHeaders(t, []TestCase{\n\t\tNewTestCase(\"User-Agent\", []string{\"curl\"}, \"\"),\n\t\tNewTestCase(\"Content-Type\", []string{\"application/protobuf\"}, \"\"),\n\t\tNewTestCase(\"X-API-Version\", []string{\"3.0\"}, \"\"),\n\t})\n\tif want := 3; got != want {\n\t\tt.Fatalf(\"expect valiate fails %d, got %d\", want, got)\n\t}\n\n\tvar buf bytes.Buffer\n\ttFatalf = fprintFatalFunc(&buf)\n\tvalidator.RequestHeaders(t, []TestCase{\n\t\tNewTestCase(\"Not-Found\", []string{\"\"}, \"\"),\n\t})\n\n\tif got, want := buf.String(), \"not found\"; !strings.Contains(got, want) {\n\t\tt.Fatalf(\"expect %q to contain %q\", got, want)\n\t}\n}\n\nfunc TestValidator_ResponseHeaders(t *testing.T) {\n\tvalidator := newValidator()\n\trand.Seed(time.Now().UnixNano())\n\tlength := 0\n\tfor {\n\t\tlength = rand.Intn(100000)\n\t\tif length > 0 {\n\t\t\tbreak\n\t\t}\n\t}\n\n\tvalidator.record.responseHeaders = map[string][]string{\n\t\t\"Content-Type\":   []string{\"application/json\"},\n\t\t\"X-API-Version\":  []string{\"1.1.2\"},\n\t\t\"Content-Length\": []string{strconv.Itoa(length)},\n\t}\n\tcontentLengthCalledAssertFunc := false\n\tvalidator.ResponseHeaders(t, []TestCase{\n\t\tNewTestCase(\"Content-Type\", \"application/json\", \"\"),\n\t\tNewTestCase(\"X-API-Version\", \"1.1.2\", \"\"),\n\t\t{\"Content-Length\", []string{\"content length\"}, \"length is change every time\", func(t *testing.T, expected, actual interface{}, desc string) {\n\t\t\tcontentLength, err := strconv.Atoi(actual.(string))\n\t\t\tif err != nil {\n\t\t\t\tt.Fatal(\"actual is not number\")\n\t\t\t}\n\t\t\tif contentLength <= 0 {\n\t\t\t\tt.Fatal(\"actual must be greater than 0\")\n\t\t\t}\n\t\t\tcontentLengthCalledAssertFunc = true\n\t\t}},\n\t})\n\n\tif contentLengthCalledAssertFunc == false {\n\t\tt.Fatal(\"content length AssertFunc should be called.\")\n\t}\n\n\tvar got int\n\tvalidator.assertFunc = testAssertWithCount(&got)\n\tvalidator.ResponseHeaders(t, []TestCase{\n\t\tNewTestCase(\"Content-Type\", []string{\"application/protobuf\"}, \"\"),\n\t})\n\tif want := 1; got != want {\n\t\tt.Fatalf(\"expect valiate fails %d, got %d\", want, got)\n\t}\n\n\tvar buf bytes.Buffer\n\ttFatalf = fprintFatalFunc(&buf)\n\tvalidator.ResponseHeaders(t, []TestCase{\n\t\tNewTestCase(\"Not-Found\", []string{\"\"}, \"\"),\n\t})\n\n\tif got, want := buf.String(), \"not found\"; !strings.Contains(got, want) {\n\t\tt.Fatalf(\"expect %q to contain %q\", got, want)\n\t}\n}\n\nfunc TestValidator_RequestBody(t *testing.T) {\n\tvalidator := newValidator()\n\tvalidator.record.requestBody = []byte(`{\n  \"id\": 910,\n  \"setting\": {\n    \"email\": \"taichi@mercari.com\"\n  }\n}\n`)\n\tvalidator.RequestBody(t, []TestCase{\n\t\tNewTestCase(\"ID\", 910, \"\"),\n\t\tNewTestCase(\"Setting.Email\", \"taichi@mercari.com\", \"\"),\n\t}, &User{})\n\n\tvar got int\n\tvalidator.assertFunc = testAssertWithCount(&got)\n\tvalidator.RequestBody(t, []TestCase{\n\t\tNewTestCase(\"ID\", 123, \"\"),\n\t\tNewTestCase(\"Active\", true, \"\"),\n\t\tNewTestCase(\"Setting.Email\", \"deeeet@gmail.com\", \"\"),\n\t}, &User{})\n\n\tif want := 3; got != want {\n\t\tt.Fatalf(\"expect valiate fails %d, got %d\", want, got)\n\t}\n\n\tvar buf bytes.Buffer\n\ttFatalf = fprintFatalFunc(&buf)\n\tvalidator.RequestBody(t, []TestCase{}, struct{}{})\n\tif got, want := buf.String(), \"Failed to unmarshal request\"; !strings.Contains(got, want) {\n\t\tt.Fatalf(\"expect %q to contain %q\", got, want)\n\t}\n}\n\nfunc TestValidator_ResponseBody(t *testing.T) {\n\tvalidator := newValidator()\n\tvalidator.record.responseBody = []byte(`{\n  \"id\": 789,\n  \"active\": false,\n  \"setting\": {\n    \"email\": \"tcnksm@mercari.com\"\n  },\n  \"permission\": [\"write\",\"read\"],\n  \"preference\": {\n    \"email\": 0\n  }\n}\n`)\n\tcustommailCalledAssertFunc := false\n\tvalidator.ResponseBody(t, []TestCase{\n\t\tNewTestCase(\"ID\", 789, \"\"),\n\t\tNewTestCase(\"Active\", false, \"\"),\n\t\tNewTestCase(\"Setting.Email\", \"tcnksm@mercari.com\", \"\"),\n\t\t{\"Setting.Email\", \"custommail\", \"\", func(t *testing.T, expected, actual interface{}, desc string) {\n\t\t\tif expected != \"custommail\" {\n\t\t\t\tt.Fatal(\"Setting.Email is not custommail\")\n\t\t\t}\n\t\t\tcustommailCalledAssertFunc = true\n\t\t}},\n\t\tNewTestCase(\"Permission[1]\", \"read\", \"\"),\n\t\t{`Preference[\"email\"]`, 0, \"\", nil},\n\t}, &User{})\n\n\tif custommailCalledAssertFunc == false {\n\t\tt.Fatal(\"custom mail AssertFunc should be called.\")\n\t}\n\n\tvar got int\n\tvalidator.assertFunc = testAssertWithCount(&got)\n\tvalidator.ResponseBody(t, []TestCase{\n\t\tNewTestCase(\"ID\", 123, \"\"),\n\t\tNewTestCase(\"Active\", true, \"\"),\n\t\tNewTestCase(\"Setting.Email\", \"deeeet@gmail.com\", \"\"),\n\t\tNewTestCase(\"Permission[1]\", \"write\", \"\"),\n\t\t{`Preference[\"email\"]`, 1, \"\", nil},\n\t}, &User{})\n\n\tif want := 5; got != want {\n\t\tt.Fatalf(\"expect valiate fails %d, got %d\", want, got)\n\t}\n\n\tvar buf bytes.Buffer\n\ttFatalf = fprintFatalFunc(&buf)\n\tvalidator.ResponseBody(t, []TestCase{}, struct{}{})\n\tif got, want := buf.String(), \"Failed to unmarshal response\"; !strings.Contains(got, want) {\n\t\tt.Fatalf(\"expect %q to contain %q\", got, want)\n\t}\n}\n\nfunc TestValidateFields(t *testing.T) {\n\ttestUser := &User{\n\t\tID:     12345,\n\t\tName:   \"tcnksm\",\n\t\tActive: true,\n\t\tSetting: &Setting{\n\t\t\tEmail: \"tcnksm@example.com\",\n\t\t\tSNS: SNS{\n\t\t\t\tTwitter: \"@deeeet\",\n\t\t\t},\n\t\t},\n\t\tPermission: []string{\"write\", \"read\"},\n\t\tPreference: map[string]int{\n\t\t\t\"email\": 0,\n\t\t\t\"push\":  1,\n\t\t},\n\t}\n\n\tactiveCalledAssertFunc := false\n\tvalidator := newValidator()\n\tvalidator.validateFields(t, []TestCase{\n\t\tNewTestCase(\"ID\", 12345, \"\"),\n\t\tNewTestCase(\"Name\", \"tcnksm\", \"\"),\n\t\tNewTestCase(\"Active\", true, \"\"),\n\t\t{\"Active\", \"customactive\", \"\", func(t *testing.T, expected, actual interface{}, desc string) {\n\t\t\tif expected != \"customactive\" {\n\t\t\t\tt.Fatal(\"Acitve is not customactive\")\n\t\t\t}\n\t\t\tactiveCalledAssertFunc = true\n\t\t}},\n\t\tNewTestCase(\"Setting.Email\", \"tcnksm@example.com\", \"\"),\n\t\tNewTestCase(\"Setting.SNS.Twitter\", \"@deeeet\", \"\"),\n\t\tNewTestCase(\"Permission[0]\", \"write\", \"\"),\n\t\t{`Preference[\"email\"]`, 0, \"\", nil},\n\t}, testUser, &[]Data{})\n\n\tif activeCalledAssertFunc == false {\n\t\tt.Fatal(\"active AssertFunc should be called.\")\n\t}\n}\n\nfunc TestValidator_RequestBody_Proto(t *testing.T) {\n\tbuf, err := proto.Marshal(&UserProtoRequest{\n\t\tId:   12345,\n\t\tName: \"tcnksm\",\n\t})\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\n\tvalidator := newValidator()\n\tvalidator.record.requestBody = buf\n\tvalidator.unmarshalFunc = protoUnmarshalFunc\n\tcustomIDCalledAssertFunc := false\n\tvalidator.RequestBody(t, []TestCase{\n\t\tNewTestCase(\"Id\", int32(12345), \"\"),\n\t\tNewTestCase(\"Name\", \"tcnksm\", \"\"),\n\t\t{\"Id\", \"customid\", \"custom assert func test\", func(t *testing.T, expected, actual interface{}, desc string) {\n\t\t\tif expected != \"customid\" {\n\t\t\t\tt.Fatal(\"expected is not customid\")\n\t\t\t}\n\t\t\tcustomIDCalledAssertFunc = true\n\t\t}},\n\t}, &UserProtoRequest{})\n\n\tif customIDCalledAssertFunc == false {\n\t\tt.Fatal(\"custom id AssertFunc should be called.\")\n\t}\n\n\tvar got int\n\tvalidator.assertFunc = testAssertWithCount(&got)\n\tvalidator.RequestBody(t, []TestCase{\n\t\tNewTestCase(\"Id\", 123, \"\"),\n\t}, &UserProtoRequest{})\n\n\tif want := 1; got != want {\n\t\tt.Fatalf(\"expect valiate fails %d, got %d\", want, got)\n\t}\n}\n\nfunc TestValidator_ResponseBody_Proto(t *testing.T) {\n\tbuf, err := proto.Marshal(&UserProtoResponse{\n\t\tId: 667854,\n\t\tSetting: &UserProtoResponse_Setting{\n\t\t\tEmail: \"httpdoc@example.com\",\n\t\t},\n\t})\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\n\tvalidator := newValidator()\n\tvalidator.unmarshalFunc = protoUnmarshalFunc\n\tvalidator.record.responseBody = buf\n\tvalidator.ResponseBody(t, []TestCase{\n\t\tNewTestCase(\"Id\", int32(667854), \"\"),\n\t\tNewTestCase(\"Setting.Email\", \"httpdoc@example.com\", \"\"),\n\t}, &UserProtoResponse{})\n\n\tvar got int\n\tvalidator.assertFunc = testAssertWithCount(&got)\n\tvalidator.ResponseBody(t, []TestCase{\n\t\tNewTestCase(\"Id\", 123, \"\"),\n\t\tNewTestCase(\"Setting.Email\", \"deeeet@gmail.com\", \"\"),\n\t}, &UserProtoResponse{})\n\n\tif want := 2; got != want {\n\t\tt.Fatalf(\"expect valiate fails %d, got %d\", want, got)\n\t}\n}\n\nfunc TestUnmarshallerFunc(t *testing.T) {\n\tunmarshalFunc := protoUnmarshalFunc\n\tif err := unmarshalFunc([]byte(\"\"), &User{}); err == nil {\n\t\tt.Fatal(\"expect to be failed\")\n\t}\n}\n\nfunc TestAssertFunc(t *testing.T) {\n\tvar buf bytes.Buffer\n\ttFatalf = fprintFatalFunc(&buf)\n\tdefaultAssertFunc(t, 1, 2, \"test-assert\")\n\tif got, want := buf.String(), \"test-assert: got 2(int), want 1(int)\"; !strings.Contains(got, want) {\n\t\tt.Fatalf(\"expect %q to contain %q\", got, want)\n\t}\n\n}\n"
  }
]