<commit_before>/*
 * Copyright 2020 Google LLC.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package importer

import (
	"testing"
)

func TestFromConfigValues(t *testing.T) {
	configs := []ProviderConfigMap{
		{
			"":       "emptyValFirst",
			"mykey1": "key1First",
			"mykey2": "key2First",
		},
		nil, // nil map to ensure it doesn't crash the check.
		{},  // Empty map just to make sure it gets skipped correctly.
		{
			"mykey1": "key1Second",
			"mykey3": "key3Second",
		},
	}

	tests := []struct {
		key     string
		cvs     []ProviderConfigMap
		want    interface{}
		wantErr bool
	}{
		// Empty configs - should return nil.
		{"", nil, nil, false},

		// Empty key - should still work.
		{"", configs, "emptyValFirst", false},

		// Key not in any config - should return nil and err.
		{"nonExistentKey", configs, nil, true},

		// Key in second config - should return second one, not nil.
		{"mykey3", configs, "key3Second", false},

		// Key in both configs - should return first one.
		{"mykey1", configs, "key1First", false},
	}
	for _, tc := range tests {
		got, err := fromConfigValues(tc.key, tc.cvs...)

		if tc.wantErr && err == nil {
			t.Errorf("fromConfigValues(%v, %v) returned nil err on nil value, expected error message", tc.key, tc.cvs)
		}

		if got != tc.want {
			t.Errorf("fromConfigValues(%v, %v) = %v; want %v", tc.key, tc.cvs, got, tc.want)
		}
	}
}
<commit_msg>Split resources_test into two tests (#38)<commit_after>/*
 * Copyright 2020 Google LLC.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package importer

import (
	"testing"
)

var configs = []ProviderConfigMap{
	{
		"":       "emptyValFirst",
		"mykey1": "key1First",
		"mykey2": "key2First",
	},
	nil, // nil map to ensure it doesn't crash the check.
	{},  // Empty map just to make sure it gets skipped correctly.
	{
		"mykey1": "key1Second",
		"mykey3": "key3Second",
	},
}

func TestFromConfigValuesGot(t *testing.T) {
	tests := []struct {
		key  string
		cvs  []ProviderConfigMap
		want interface{}
	}{
		// Empty key - should still work.
		{"", configs, "emptyValFirst"},

		// Key in second config - should return second one, not nil.
		{"mykey3", configs, "key3Second"},

		// Key in both configs - should return first one.
		{"mykey1", configs, "key1First"},
	}
	for _, tc := range tests {
		got, err := fromConfigValues(tc.key, tc.cvs...)
		if err != nil {
			t.Errorf("fromConfigValues(%v, %v) failed: %s", tc.key, tc.cvs, err)
		}
		if got != tc.want {
			t.Errorf("fromConfigValues(%v, %v) = %v; want %v", tc.key, tc.cvs, got, tc.want)
		}
	}
}

func TestFromConfigValuesErr(t *testing.T) {
	tests := []struct {
		key string
		cvs []ProviderConfigMap
	}{
		// Empty configs - should return err.
		{"", nil},

		// Key not in any config - should return err.
		{"nonExistentKey", configs},
	}
	for _, tc := range tests {
		if _, err := fromConfigValues(tc.key, tc.cvs...); err == nil {
			t.Errorf("fromConfigValues(%v, %v) succeeded for malformed input, want error", tc.key, tc.cvs)
		}
	}
}
<|endoftext|>


<commit_before>package buffalo

import (
	"context"
	"fmt"
	"net/http"
	"strings"

	"github.com/fatih/color"
	"github.com/gobuffalo/buffalo/internal/defaults"
	"github.com/gobuffalo/buffalo/worker"
	"github.com/gobuffalo/envy"
	"github.com/gobuffalo/logger"
	"github.com/gobuffalo/pop/v6"
	"github.com/gobuffalo/pop/v6/logging"
	"github.com/gorilla/sessions"
	"github.com/markbates/oncer"
)

// Options are used to configure and define how your application should run.
type Options struct {
	Name string `json:"name"`
	// Addr is the bind address provided to http.Server. Default is "127.0.0.1:3000"
	// Can be set using ENV vars "ADDR" and "PORT".
	Addr string `json:"addr"`
	// Host that this application will be available at. Default is "http://127.0.0.1:[$PORT|3000]".
	Host string `json:"host"`

	// Env is the "environment" in which the App is running. Default is "development".
	Env string `json:"env"`

	// LogLevel defaults to "debug". Deprecated use LogLvl instead
	LogLevel string `json:"log_level"`
	// LogLevl defaults to logger.DebugLvl.
	LogLvl logger.Level `json:"log_lvl"`
	// Logger to be used with the application. A default one is provided.
	Logger Logger `json:"-"`

	// MethodOverride allows for changing of the request method type. See the default
	// implementation at buffalo.MethodOverride
	MethodOverride http.HandlerFunc `json:"-"`

	// SessionStore is the `github.com/gorilla/sessions` store used to back
	// the session. It defaults to use a cookie store and the ENV variable
	// `SESSION_SECRET`.
	SessionStore sessions.Store `json:"-"`
	// SessionName is the name of the session cookie that is set. This defaults
	// to "_buffalo_session".
	SessionName string `json:"session_name"`

	// Worker implements the Worker interface and can process tasks in the background.
	// Default is "github.com/gobuffalo/worker.Simple.
	Worker worker.Worker `json:"-"`
	// WorkerOff tells App.Start() whether to start the Worker process or not. Default is "false".
	WorkerOff bool `json:"worker_off"`

	// PreHandlers are http.Handlers that are called between the http.Server
	// and the buffalo Application.
	PreHandlers []http.Handler `json:"-"`
	// PreWare takes an http.Handler and returns and http.Handler
	// and acts as a pseudo-middleware between the http.Server and
	// a Buffalo application.
	PreWares []PreWare `json:"-"`

	// CompressFiles enables gzip compression of static files served by ServeFiles using
	// gorilla's CompressHandler (https://godoc.org/github.com/gorilla/handlers#CompressHandler).
	// Default is "false".
	CompressFiles bool `json:"compress_files"`

	Prefix  string          `json:"prefix"`
	Context context.Context `json:"-"`

	cancel context.CancelFunc
}

// PreWare takes an http.Handler and returns and http.Handler
// and acts as a pseudo-middleware between the http.Server and
// a Buffalo application.
type PreWare func(http.Handler) http.Handler

// NewOptions returns a new Options instance with sensible defaults
func NewOptions() Options {
	return optionsWithDefaults(Options{})
}

func optionsWithDefaults(opts Options) Options {
	opts.Env = defaults.String(opts.Env, envy.Get("GO_ENV", "development"))
	opts.Name = defaults.String(opts.Name, "/")
	addr := "0.0.0.0"
	if opts.Env == "development" {
		addr = "127.0.0.1"
	}
	envAddr := envy.Get("ADDR", addr)

	if strings.HasPrefix(envAddr, "unix:") {
		// UNIX domain socket doesn't have a port
		opts.Addr = envAddr
	} else {
		// TCP case
		opts.Addr = defaults.String(opts.Addr, fmt.Sprintf("%s:%s", envAddr, envy.Get("PORT", "3000")))
	}

	if opts.PreWares == nil {
		opts.PreWares = []PreWare{}
	}
	if opts.PreHandlers == nil {
		opts.PreHandlers = []http.Handler{}
	}

	if opts.Context == nil {
		opts.Context = context.Background()
	}
	opts.Context, opts.cancel = context.WithCancel(opts.Context)

	if opts.Logger == nil {
		if lvl, err := envy.MustGet("LOG_LEVEL"); err == nil {
			opts.LogLvl, err = logger.ParseLevel(lvl)
			if err != nil {
				opts.LogLvl = logger.DebugLevel
			}
		}

		if len(opts.LogLevel) > 0 {
			var err error
			oncer.Deprecate(0, "github.com/gobuffalo/buffalo#Options.LogLevel", "Use github.com/gobuffalo/buffalo#Options.LogLvl instead.")
			opts.LogLvl, err = logger.ParseLevel(opts.LogLevel)
			if err != nil {
				opts.LogLvl = logger.DebugLevel
			}
		}
		if opts.LogLvl == 0 {
			opts.LogLvl = logger.DebugLevel
		}

		opts.Logger = logger.New(opts.LogLvl)
	}

	pop.SetLogger(func(level logging.Level, s string, args ...interface{}) {
		if !pop.Debug {
			return
		}

		l := opts.Logger
		if len(args) > 0 {
			for i, a := range args {
				l = l.WithField(fmt.Sprintf("$%d", i+1), a)
			}
		}

		if pop.Color {
			s = color.YellowString(s)
		}

		l.Debug(s)
	})

	if opts.SessionStore == nil {
		secret := envy.Get("SESSION_SECRET", "")

		if secret == "" && (opts.Env == "development" || opts.Env == "test") {
			secret = "buffalo-secret"
		}

		// In production a SESSION_SECRET must be set!
		if secret == "" {
			opts.Logger.Warn("Unless you set SESSION_SECRET env variable, your session storage is not protected!")
		}

		cookieStore := sessions.NewCookieStore([]byte(secret))

		//Cookie secure attributes, see: https://www.owasp.org/index.php/Testing_for_cookies_attributes_(OTG-SESS-002)
		cookieStore.Options.HttpOnly = true
		if opts.Env == "production" {
			cookieStore.Options.Secure = true
		}

		opts.SessionStore = cookieStore
	}
	if opts.Worker == nil {
		w := worker.NewSimpleWithContext(opts.Context)
		w.Logger = opts.Logger
		opts.Worker = w
	}
	opts.SessionName = defaults.String(opts.SessionName, "_buffalo_session")
	opts.Host = defaults.String(opts.Host, envy.Get("HOST", fmt.Sprintf("http://127.0.0.1:%s", envy.Get("PORT", "3000"))))
	return opts
}
<commit_msg>Fix typo in doc for PreWare and PreWares<commit_after>package buffalo

import (
	"context"
	"fmt"
	"net/http"
	"strings"

	"github.com/fatih/color"
	"github.com/gobuffalo/buffalo/internal/defaults"
	"github.com/gobuffalo/buffalo/worker"
	"github.com/gobuffalo/envy"
	"github.com/gobuffalo/logger"
	"github.com/gobuffalo/pop/v6"
	"github.com/gobuffalo/pop/v6/logging"
	"github.com/gorilla/sessions"
	"github.com/markbates/oncer"
)

// Options are used to configure and define how your application should run.
type Options struct {
	Name string `json:"name"`
	// Addr is the bind address provided to http.Server. Default is "127.0.0.1:3000"
	// Can be set using ENV vars "ADDR" and "PORT".
	Addr string `json:"addr"`
	// Host that this application will be available at. Default is "http://127.0.0.1:[$PORT|3000]".
	Host string `json:"host"`

	// Env is the "environment" in which the App is running. Default is "development".
	Env string `json:"env"`

	// LogLevel defaults to "debug". Deprecated use LogLvl instead
	LogLevel string `json:"log_level"`
	// LogLevl defaults to logger.DebugLvl.
	LogLvl logger.Level `json:"log_lvl"`
	// Logger to be used with the application. A default one is provided.
	Logger Logger `json:"-"`

	// MethodOverride allows for changing of the request method type. See the default
	// implementation at buffalo.MethodOverride
	MethodOverride http.HandlerFunc `json:"-"`

	// SessionStore is the `github.com/gorilla/sessions` store used to back
	// the session. It defaults to use a cookie store and the ENV variable
	// `SESSION_SECRET`.
	SessionStore sessions.Store `json:"-"`
	// SessionName is the name of the session cookie that is set. This defaults
	// to "_buffalo_session".
	SessionName string `json:"session_name"`

	// Worker implements the Worker interface and can process tasks in the background.
	// Default is "github.com/gobuffalo/worker.Simple.
	Worker worker.Worker `json:"-"`
	// WorkerOff tells App.Start() whether to start the Worker process or not. Default is "false".
	WorkerOff bool `json:"worker_off"`

	// PreHandlers are http.Handlers that are called between the http.Server
	// and the buffalo Application.
	PreHandlers []http.Handler `json:"-"`
	// PreWare takes an http.Handler and returns an http.Handler
	// and acts as a pseudo-middleware between the http.Server and
	// a Buffalo application.
	PreWares []PreWare `json:"-"`

	// CompressFiles enables gzip compression of static files served by ServeFiles using
	// gorilla's CompressHandler (https://godoc.org/github.com/gorilla/handlers#CompressHandler).
	// Default is "false".
	CompressFiles bool `json:"compress_files"`

	Prefix  string          `json:"prefix"`
	Context context.Context `json:"-"`

	cancel context.CancelFunc
}

// PreWare takes an http.Handler and returns an http.Handler
// and acts as a pseudo-middleware between the http.Server and
// a Buffalo application.
type PreWare func(http.Handler) http.Handler

// NewOptions returns a new Options instance with sensible defaults
func NewOptions() Options {
	return optionsWithDefaults(Options{})
}

func optionsWithDefaults(opts Options) Options {
	opts.Env = defaults.String(opts.Env, envy.Get("GO_ENV", "development"))
	opts.Name = defaults.String(opts.Name, "/")
	addr := "0.0.0.0"
	if opts.Env == "development" {
		addr = "127.0.0.1"
	}
	envAddr := envy.Get("ADDR", addr)

	if strings.HasPrefix(envAddr, "unix:") {
		// UNIX domain socket doesn't have a port
		opts.Addr = envAddr
	} else {
		// TCP case
		opts.Addr = defaults.String(opts.Addr, fmt.Sprintf("%s:%s", envAddr, envy.Get("PORT", "3000")))
	}

	if opts.PreWares == nil {
		opts.PreWares = []PreWare{}
	}
	if opts.PreHandlers == nil {
		opts.PreHandlers = []http.Handler{}
	}

	if opts.Context == nil {
		opts.Context = context.Background()
	}
	opts.Context, opts.cancel = context.WithCancel(opts.Context)

	if opts.Logger == nil {
		if lvl, err := envy.MustGet("LOG_LEVEL"); err == nil {
			opts.LogLvl, err = logger.ParseLevel(lvl)
			if err != nil {
				opts.LogLvl = logger.DebugLevel
			}
		}

		if len(opts.LogLevel) > 0 {
			var err error
			oncer.Deprecate(0, "github.com/gobuffalo/buffalo#Options.LogLevel", "Use github.com/gobuffalo/buffalo#Options.LogLvl instead.")
			opts.LogLvl, err = logger.ParseLevel(opts.LogLevel)
			if err != nil {
				opts.LogLvl = logger.DebugLevel
			}
		}
		if opts.LogLvl == 0 {
			opts.LogLvl = logger.DebugLevel
		}

		opts.Logger = logger.New(opts.LogLvl)
	}

	pop.SetLogger(func(level logging.Level, s string, args ...interface{}) {
		if !pop.Debug {
			return
		}

		l := opts.Logger
		if len(args) > 0 {
			for i, a := range args {
				l = l.WithField(fmt.Sprintf("$%d", i+1), a)
			}
		}

		if pop.Color {
			s = color.YellowString(s)
		}

		l.Debug(s)
	})

	if opts.SessionStore == nil {
		secret := envy.Get("SESSION_SECRET", "")

		if secret == "" && (opts.Env == "development" || opts.Env == "test") {
			secret = "buffalo-secret"
		}

		// In production a SESSION_SECRET must be set!
		if secret == "" {
			opts.Logger.Warn("Unless you set SESSION_SECRET env variable, your session storage is not protected!")
		}

		cookieStore := sessions.NewCookieStore([]byte(secret))

		//Cookie secure attributes, see: https://www.owasp.org/index.php/Testing_for_cookies_attributes_(OTG-SESS-002)
		cookieStore.Options.HttpOnly = true
		if opts.Env == "production" {
			cookieStore.Options.Secure = true
		}

		opts.SessionStore = cookieStore
	}
	if opts.Worker == nil {
		w := worker.NewSimpleWithContext(opts.Context)
		w.Logger = opts.Logger
		opts.Worker = w
	}
	opts.SessionName = defaults.String(opts.SessionName, "_buffalo_session")
	opts.Host = defaults.String(opts.Host, envy.Get("HOST", fmt.Sprintf("http://127.0.0.1:%s", envy.Get("PORT", "3000"))))
	return opts
}
<|endoftext|>


<commit_before>package telebot

// ParseMode is new bot api released at Sep 7, 2015. It adds markdown support to sendMessage API
type ParseMode string

// Supported ParseMode
const (
	ModeDefault ParseMode = ""
	ModeMarkdown ParseMode = "Markdown"
)

// SendOptions represents a set of custom options that could
// be appled to messages sent.
type SendOptions struct {
	// If the message is a reply, original message.
	ReplyTo Message

	// See ReplyMarkup struct definition.
	ReplyMarkup ReplyMarkup

	// For text messages, disables previews for links in this message.
	DisableWebPagePreview bool

	// ParseMode controls how client apps render your message.
	ParseMode ParseMode
}

type ReplyMarkup struct {
	// ForceReply forces Telegram clients to display
	// a reply interface to the user (act as if the user
	// has selected the bot‘s message and tapped "Reply").
	ForceReply bool `json:"force_reply,omitempty"`

	// CustomKeyboard is Array of button rows, each represented by an Array of Strings.
	//
	// Note: you don't need to set HideCustomKeyboard field to show custom keyboard.
	CustomKeyboard [][]string `json:"keyboard,omitempty"`
	// Requests clients to resize the keyboard vertically for optimal fit
	// (e.g., make the keyboard smaller if there are just two rows of buttons).
	// Defaults to false, in which case the custom keyboard is always of the
	// same height as the app's standard keyboard.
	ResizeKeyboard bool `json:"resize_keyboard,omitemptyd"`
	// Requests clients to hide the keyboard as soon as it's been used. Defaults to false.
	OneTimeKeyboard bool `json:"one_time_keyboard,omitempty"`

	// Requests clients to hide the custom keyboard.
	//
	// Note: You dont need to set CustomKeyboard field to hide custom keyboard.
	HideCustomKeyboard bool `json:"hide_keyboard,omitempty"`

	// Use this param if you want to force reply from
	// specific users only.
	//
	// Targets:
	// 1) Users that are @mentioned in the text of the Message object;
	// 2) If the bot's message is a reply (has SendOptions.ReplyTo),
	//       sender of the original message.
	Selective bool `json:"selective,omitempty"`
}
<commit_msg>update documentation<commit_after>package telebot

// ParseMode determines the way client applications treat the text of the message
type ParseMode string

// Supported ParseMode
const (
	ModeDefault ParseMode = ""
	ModeMarkdown ParseMode = "Markdown"
)

// SendOptions represents a set of custom options that could
// be appled to messages sent.
type SendOptions struct {
	// If the message is a reply, original message.
	ReplyTo Message

	// See ReplyMarkup struct definition.
	ReplyMarkup ReplyMarkup

	// For text messages, disables previews for links in this message.
	DisableWebPagePreview bool

	// ParseMode controls how client apps render your message.
	ParseMode ParseMode
}

type ReplyMarkup struct {
	// ForceReply forces Telegram clients to display
	// a reply interface to the user (act as if the user
	// has selected the bot‘s message and tapped "Reply").
	ForceReply bool `json:"force_reply,omitempty"`

	// CustomKeyboard is Array of button rows, each represented by an Array of Strings.
	//
	// Note: you don't need to set HideCustomKeyboard field to show custom keyboard.
	CustomKeyboard [][]string `json:"keyboard,omitempty"`
	// Requests clients to resize the keyboard vertically for optimal fit
	// (e.g., make the keyboard smaller if there are just two rows of buttons).
	// Defaults to false, in which case the custom keyboard is always of the
	// same height as the app's standard keyboard.
	ResizeKeyboard bool `json:"resize_keyboard,omitemptyd"`
	// Requests clients to hide the keyboard as soon as it's been used. Defaults to false.
	OneTimeKeyboard bool `json:"one_time_keyboard,omitempty"`

	// Requests clients to hide the custom keyboard.
	//
	// Note: You dont need to set CustomKeyboard field to hide custom keyboard.
	HideCustomKeyboard bool `json:"hide_keyboard,omitempty"`

	// Use this param if you want to force reply from
	// specific users only.
	//
	// Targets:
	// 1) Users that are @mentioned in the text of the Message object;
	// 2) If the bot's message is a reply (has SendOptions.ReplyTo),
	//       sender of the original message.
	Selective bool `json:"selective,omitempty"`
}
<|endoftext|>


<commit_before>package controllers

import (
	"github.com/astaxie/beego"
	woothee "github.com/woothee/woothee-go"
)

type Meta struct {
	AppName         string
	AntennaURL      string
	BookURL         string
	VideoURL        string
	Copyright       string
	Author          string
	Email           string
	Keywords        string
	Description     string
	ApplicationName string
	Domain          string
	BaseDomain      string
	Host            string
	Url             string
	Type            string
	Title           string
	Image           string
	SiteName        string
	Locale          string
	FBAppId         string
	TWCard          string
	TWDomain        string
	TWSite          string
	TWImage         string
	RunMode         string
	UA              *woothee.Result
}

func NewMeta() *Meta {
	return &Meta{
		AppName:         beego.AppConfig.String("AppName"),
		AntennaURL:      beego.AppConfig.String("antennaurl"),
		BookURL:         beego.AppConfig.String("bookurl"),
		VideoURL:        beego.AppConfig.String("videourl"),
		Copyright:       beego.AppConfig.String("SiteName"),
		Author:          beego.AppConfig.String("Author"),
		Email:           beego.AppConfig.String("Email"),
		Keywords:        beego.AppConfig.String("Keywords"),
		Description:     beego.AppConfig.String("Description"),
		ApplicationName: beego.AppConfig.String("SiteName"),
		Domain:          beego.AppConfig.String("domain"),
		BaseDomain:      beego.AppConfig.String("basedomain"),
		Host:            "",
		Url:             "",
		Type:            "article",
		Title:           beego.AppConfig.String("SiteName"),
		Image:           beego.AppConfig.String("Image"),
		SiteName:        beego.AppConfig.String("SiteName"),
		Locale:          "ja_JP",
		FBAppId:         beego.AppConfig.String("FBAppId"),
		TWCard:          "summary_large_image",
		TWDomain:        "//",
		TWSite:          "//",
		TWImage:         beego.AppConfig.String("Image"),
		RunMode:         beego.RunMode,
	}
}

func (m *Meta) Init(c *BaseController) {
	m.Url = c.BuildRequestUrl("")
	m.Host = c.Ctx.Input.Site()
	m.UA, _ = woothee.Parse(c.Ctx.Input.UserAgent())
}
<commit_msg>fixed meta struct<commit_after>package controllers

import (
	"github.com/astaxie/beego"
	woothee "github.com/woothee/woothee-go"
)

type Meta struct {
	AppName         string
	AntennaURL      string
	BookURL         string
	VideoURL        string
	DicURL          string
	Copyright       string
	Author          string
	Email           string
	Keywords        string
	Description     string
	ApplicationName string
	Domain          string
	BaseDomain      string
	Host            string
	Url             string
	Type            string
	Title           string
	Image           string
	SiteName        string
	Locale          string
	FBAppId         string
	TWCard          string
	TWDomain        string
	TWSite          string
	TWImage         string
	RunMode         string
	UA              *woothee.Result
}

func NewMeta() *Meta {
	return &Meta{
		AppName:         beego.AppConfig.String("AppName"),
		AntennaURL:      beego.AppConfig.String("antennaurl"),
		BookURL:         beego.AppConfig.String("bookurl"),
		DicURL:          beego.AppConfig.String("dicurl"),
		VideoURL:        beego.AppConfig.String("videourl"),
		Copyright:       beego.AppConfig.String("SiteName"),
		Author:          beego.AppConfig.String("Author"),
		Email:           beego.AppConfig.String("Email"),
		Keywords:        beego.AppConfig.String("Keywords"),
		Description:     beego.AppConfig.String("Description"),
		ApplicationName: beego.AppConfig.String("SiteName"),
		Domain:          beego.AppConfig.String("domain"),
		BaseDomain:      beego.AppConfig.String("basedomain"),
		Host:            "",
		Url:             "",
		Type:            "article",
		Title:           beego.AppConfig.String("SiteName"),
		Image:           beego.AppConfig.String("Image"),
		SiteName:        beego.AppConfig.String("SiteName"),
		Locale:          "ja_JP",
		FBAppId:         beego.AppConfig.String("FBAppId"),
		TWCard:          "summary_large_image",
		TWDomain:        "//",
		TWSite:          "//",
		TWImage:         beego.AppConfig.String("Image"),
		RunMode:         beego.RunMode,
	}
}

func (m *Meta) Init(c *BaseController) {
	m.Url = c.BuildRequestUrl("")
	m.Host = c.Ctx.Input.Site()
	m.UA, _ = woothee.Parse(c.Ctx.Input.UserAgent())
}
<|endoftext|>


<commit_before>package identity

import ()

var (
	// Level to use in signing when registering
	RegisterIdentityLevel int = 1
	// For ChainIDs
	ProofOfWorkChainID     = []byte{0x88, 0x88, 0x88}
	ProofOfWorkLength  int = 3 // DEFAULT = 3, set lower for faster tests
	// For Registering Root Chain
	// e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
	RootRegisterChain string = "1d1d1d1d07714fea910f9c6e42e5dc072c86491a3d80418855a2499e85b0039f"
	// If true will show "." on screen to show user program is computing
	ShowBruteForce bool = true
	// Will change frequency of dots for brute forcing
	BruteForcePeriod int = 400000
	// Amount of hashes on seed to generate MHash
	MHashAmount int = 100000
	//Seed Hex Length (length/2 = bytes)
	SeedMin int = 4
	SeedMax int = 64
	// Curl Commands for Milestone 1 or 2
	Version int = 2
)
<commit_msg>Changed to new chain<commit_after>package identity

import ()

var (
	// Level to use in signing when registering
	RegisterIdentityLevel int = 1
	// For ChainIDs
	ProofOfWorkChainID     = []byte{0x88, 0x88, 0x88}
	ProofOfWorkLength  int = 3 // DEFAULT = 3, set lower for faster tests
	// For Registering Root Chain
	// e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
	RootRegisterChain string = "888888001750ede0eff4b05f0c3f557890b256450cabbb84cada937f9c258327"
	// If true will show "." on screen to show user program is computing
	ShowBruteForce bool = true
	// Will change frequency of dots for brute forcing
	BruteForcePeriod int = 400000
	// Amount of hashes on seed to generate MHash
	MHashAmount int = 100000
	//Seed Hex Length (length/2 = bytes)
	SeedMin int = 4
	SeedMax int = 64
	// Curl Commands for Milestone 1 or 2
	Version int = 2
)
<|endoftext|>


<commit_before>package luddite

import (
	"encoding/xml"
	"fmt"
)

const (
	// Common error codes
	EcodeUnknown               = 0
	EcodeInternal              = 1
	EcodeUnsupportedMediaType  = 2
	EcodeSerializationFailed   = 3
	EcodeDeserializationFailed = 4
	EcodeIdentifierMismatch    = 5

	// Service-specific error codes
	EcodeServiceBase = 1024
)

var commonErrorMessages = map[int]string{
	EcodeUnknown:               "Unknown error",
	EcodeInternal:              "Internal error",
	EcodeUnsupportedMediaType:  "Unsupported media type: %s",
	EcodeSerializationFailed:   "Serialization failed: %s",
	EcodeDeserializationFailed: "Deserialization failed: %s",
	EcodeIdentifierMismatch:    "Resource identifier in URL doesn't match value in body",
}

// Error is a structured error that is returned as the body in all 4xx and 5xx responses.
type Error struct {
	XMLName xml.Name `json:"-" xml:"error"`
	Code    int      `json:"code" xml:"code"`
	Message string   `json:"message" xml:"message"`
	Stack   string   `json:"stack,omitempty" xml:"stack,omitempty"`
}

func (e *Error) Error() string {
	return e.Message
}

func NewError(errorMessages map[int]string, code int, args ...interface{}) *Error {
	var (
		format string
		ok     bool
	)

	// Lookup an error message string by error code
	if errorMessages != nil {
		format, ok = errorMessages[code]
	} else {
		format, ok = commonErrorMessages[code]
	}

	// If no message was found, use a known-safe error message along with the caller's error code
	if !ok {
		format = commonErrorMessages[EcodeUnknown]
		args = nil
	}

	// Optionally format the error message
	var message string
	if len(args) != 0 {
		message = fmt.Sprintf(format, args...)
	} else {
		message = format
	}

	return &Error{
		Code:    code,
		Message: message,
	}
}
<commit_msg>Added code comment for NewError.<commit_after>package luddite

import (
	"encoding/xml"
	"fmt"
)

const (
	// Common error codes
	EcodeUnknown               = 0
	EcodeInternal              = 1
	EcodeUnsupportedMediaType  = 2
	EcodeSerializationFailed   = 3
	EcodeDeserializationFailed = 4
	EcodeIdentifierMismatch    = 5

	// Service-specific error codes
	EcodeServiceBase = 1024
)

var commonErrorMessages = map[int]string{
	EcodeUnknown:               "Unknown error",
	EcodeInternal:              "Internal error",
	EcodeUnsupportedMediaType:  "Unsupported media type: %s",
	EcodeSerializationFailed:   "Serialization failed: %s",
	EcodeDeserializationFailed: "Deserialization failed: %s",
	EcodeIdentifierMismatch:    "Resource identifier in URL doesn't match value in body",
}

// Error is a structured error that is returned as the body in all 4xx and 5xx responses.
type Error struct {
	XMLName xml.Name `json:"-" xml:"error"`
	Code    int      `json:"code" xml:"code"`
	Message string   `json:"message" xml:"message"`
	Stack   string   `json:"stack,omitempty" xml:"stack,omitempty"`
}

func (e *Error) Error() string {
	return e.Message
}

// NewError allocates and initializes an Error. If a non-nil
// errorMessages map is passed, the error message string is resolved
// using this map. Otherwise a map containing common error message
// strings is used. Services or resources should generally use error
// code values greater than or equal to EcodeServiceBase. Error codes
// below this value are reserved for common use.
func NewError(errorMessages map[int]string, code int, args ...interface{}) *Error {
	var (
		format string
		ok     bool
	)

	// Lookup an error message string by error code
	if errorMessages != nil {
		format, ok = errorMessages[code]
	} else {
		format, ok = commonErrorMessages[code]
	}

	// If no message was found, use a known-safe error message along with the caller's error code
	if !ok {
		format = commonErrorMessages[EcodeUnknown]
		args = nil
	}

	// Optionally format the error message
	var message string
	if len(args) != 0 {
		message = fmt.Sprintf(format, args...)
	} else {
		message = format
	}

	return &Error{
		Code:    code,
		Message: message,
	}
}
<|endoftext|>


<commit_before>//Package gjwt validates Google JWT tokens using the list of public keys published. This list is kept up-to-date automatically.
package gjwt

import (
	"crypto/rsa"
	"crypto/x509"
	"encoding/json"
	"encoding/pem"
	"errors"
	"flag"
	"fmt"
	"io/ioutil"
	"net/http"
	"strings"
	"sync"
	"time"

	"github.com/dgrijalva/jwt-go"
)

type keychain struct {
	sync.Mutex
	keys map[string][]byte
}

var (
	mainKeychain    = &keychain{sync.Mutex{}, make(map[string][]byte)}
	flagSet         = flag.NewFlagSet("gjwt", flag.PanicOnError)
	certificatesURL = flagSet.String("certificates_url", "https://www.googleapis.com/oauth2/v1/certs", "Google signing certificates URL")
)

func init() {
	flag.Parse()
	loadPublicKeys(time.Second)
}

func loadPublicKeys(previousDelay time.Duration) {
	if previousDelay > 60.0*time.Second {
		previousDelay = time.Second
	}

	nextRun, err := updateKeys()
	if err != nil {
		nextRun = previousDelay * 2.0
	}

	// got here? no problems, schedule next run at expiry time
	time.AfterFunc(nextRun, func() {
		loadPublicKeys(nextRun)
	})
}

func updateKeys() (time.Duration, error) {
	req, err := http.NewRequest("GET", *certificatesURL, nil)
	if err != nil {
		return 0, err
	}
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		return 0, err
	}

	if res.StatusCode != 200 {
		return 0, errors.New(res.Status)
	}

	ageSeconds := res.Header.Get(http.CanonicalHeaderKey("age"))
	age, err := time.ParseDuration(fmt.Sprintf("%ss", ageSeconds))
	if err != nil {
		return 0, err
	}

	var maxAgeSeconds string
	cacheControl := res.Header[http.CanonicalHeaderKey("cache-control")]
	for _, v := range cacheControl {
		items := strings.Split(v, ",")
		for _, vv := range items {
			maxAgeItems := strings.Split(vv, "=")
			if len(maxAgeItems) == 2 {
				maxAgeSeconds = maxAgeItems[1]
			}
		}
	}

	maxAge, err := time.ParseDuration(fmt.Sprintf("%ss", maxAgeSeconds))
	if err != nil {
		return 0, err
	}

	var expiresIn = maxAge - age
	keysJSON, err := ioutil.ReadAll(res.Body)
	if err != nil {
		return 0, err
	}

	var certKeys map[string]string
	if err := json.Unmarshal(keysJSON, &certKeys); err != nil {
		return 0, err
	}

	for x := range certKeys {
		// decode certificate
		block, _ := pem.Decode([]byte(certKeys[x]))
		var cert *x509.Certificate
		cert, err = x509.ParseCertificate(block.Bytes)
		if err != nil {
			return 0, err
		}

		// marshal pure public key from certificate
		rsaPublicKey := cert.PublicKey.(*rsa.PublicKey)
		pubKey, err := x509.MarshalPKIXPublicKey(rsaPublicKey)
		if err != nil {
			return 0, err
		}

		// create pubkey pem representation
		pubKeyPem := pem.EncodeToMemory(&pem.Block{
			Type:  "RSA PUBLIC KEY",
			Bytes: pubKey,
		})

		// update keychain
		mainKeychain.Lock()
		mainKeychain.keys[x] = pubKeyPem
		mainKeychain.Unlock()
	}

	return expiresIn, nil
}

// Validate validates a JWT token against Google's public keys. It returns a *jwt.Token if successful. The caller of this function _must_ validate that the correct "aud" claim is set (see confused deputy problem).
func Validate(tokenStr string) (*jwt.Token, error) {
	token, err := jwt.Parse(tokenStr, func(token *jwt.Token) (interface{}, error) {
		// Don't forget to validate the alg is what you expect:
		if _, ok := token.Method.(*jwt.SigningMethodRSA); !ok {
			return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"])
		}
		mainKeychain.Lock()
		key, ok := mainKeychain.keys[token.Header["kid"].(string)]
		mainKeychain.Unlock()
		if !ok {
			return nil, fmt.Errorf("Cannot find key")
		}
		return key, nil
	})

	if err != nil || !token.Valid {
		return nil, err
	}

	return token, nil
}
<commit_msg>Removed flagset<commit_after>//Package gjwt validates Google JWT tokens using the list of public keys published. This list is kept up-to-date automatically.
package gjwt

import (
	"crypto/rsa"
	"crypto/x509"
	"encoding/json"
	"encoding/pem"
	"errors"
	"flag"
	"fmt"
	"io/ioutil"
	"net/http"
	"strings"
	"sync"
	"time"

	"github.com/dgrijalva/jwt-go"
)

type keychain struct {
	sync.Mutex
	keys map[string][]byte
}

var (
	mainKeychain    = &keychain{sync.Mutex{}, make(map[string][]byte)}
	certificatesURL = flag.String("certificates_url", "https://www.googleapis.com/oauth2/v1/certs", "Google signing certificates URL")
)

func init() {
	flag.Parse()
	loadPublicKeys(time.Second)
}

func loadPublicKeys(previousDelay time.Duration) {
	if previousDelay > 60.0*time.Second {
		previousDelay = time.Second
	}

	nextRun, err := updateKeys()
	if err != nil {
		nextRun = previousDelay * 2.0
	}

	// got here? no problems, schedule next run at expiry time
	time.AfterFunc(nextRun, func() {
		loadPublicKeys(nextRun)
	})
}

func updateKeys() (time.Duration, error) {
	req, err := http.NewRequest("GET", *certificatesURL, nil)
	if err != nil {
		return 0, err
	}
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		return 0, err
	}

	if res.StatusCode != 200 {
		return 0, errors.New(res.Status)
	}

	ageSeconds := res.Header.Get(http.CanonicalHeaderKey("age"))
	age, err := time.ParseDuration(fmt.Sprintf("%ss", ageSeconds))
	if err != nil {
		return 0, err
	}

	var maxAgeSeconds string
	cacheControl := res.Header[http.CanonicalHeaderKey("cache-control")]
	for _, v := range cacheControl {
		items := strings.Split(v, ",")
		for _, vv := range items {
			maxAgeItems := strings.Split(vv, "=")
			if len(maxAgeItems) == 2 {
				maxAgeSeconds = maxAgeItems[1]
			}
		}
	}

	maxAge, err := time.ParseDuration(fmt.Sprintf("%ss", maxAgeSeconds))
	if err != nil {
		return 0, err
	}

	var expiresIn = maxAge - age
	keysJSON, err := ioutil.ReadAll(res.Body)
	if err != nil {
		return 0, err
	}

	var certKeys map[string]string
	if err := json.Unmarshal(keysJSON, &certKeys); err != nil {
		return 0, err
	}

	for x := range certKeys {
		// decode certificate
		block, _ := pem.Decode([]byte(certKeys[x]))
		var cert *x509.Certificate
		cert, err = x509.ParseCertificate(block.Bytes)
		if err != nil {
			return 0, err
		}

		// marshal pure public key from certificate
		rsaPublicKey := cert.PublicKey.(*rsa.PublicKey)
		pubKey, err := x509.MarshalPKIXPublicKey(rsaPublicKey)
		if err != nil {
			return 0, err
		}

		// create pubkey pem representation
		pubKeyPem := pem.EncodeToMemory(&pem.Block{
			Type:  "RSA PUBLIC KEY",
			Bytes: pubKey,
		})

		// update keychain
		mainKeychain.Lock()
		mainKeychain.keys[x] = pubKeyPem
		mainKeychain.Unlock()
	}

	return expiresIn, nil
}

// Validate validates a JWT token against Google's public keys. It returns a *jwt.Token if successful. The caller of this function _must_ validate that the correct "aud" claim is set (see confused deputy problem).
func Validate(tokenStr string) (*jwt.Token, error) {
	token, err := jwt.Parse(tokenStr, func(token *jwt.Token) (interface{}, error) {
		// Don't forget to validate the alg is what you expect:
		if _, ok := token.Method.(*jwt.SigningMethodRSA); !ok {
			return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"])
		}
		mainKeychain.Lock()
		key, ok := mainKeychain.keys[token.Header["kid"].(string)]
		mainKeychain.Unlock()
		if !ok {
			return nil, fmt.Errorf("Cannot find key")
		}
		return key, nil
	})

	if err != nil || !token.Valid {
		return nil, err
	}

	return token, nil
}
<|endoftext|>


<commit_before>package app

import (
	"reflect"
	"sync"

	"github.com/google/uuid"
	"github.com/murlokswarm/app/key"
	"github.com/pkg/errors"
)

var (
	// DefaultEventRegistry is the default event registry.
	DefaultEventRegistry EventRegistry
)

// EventRegistry is the interface that describes an event registry.
type EventRegistry interface {
	// Subscribe subscribes the given handler to the named event.
	// It panics if handler is not a func.
	Subscribe(name string, handler interface{}) (unsuscribe func())

	EventDispatcher
}

// EventDispatcher is the interface that describes an event dispatcher.
type EventDispatcher interface {
	// Dispatch dispatches the named event with the given argument.
	// It is done on the UI goroutine.
	Dispatch(name string, arg interface{})
}

type eventHandler struct {
	ID      uuid.UUID
	Handler interface{}
}

// NewEventRegistry creates an event registry.
func NewEventRegistry(dispatcher func(func())) EventRegistry {
	return &eventRegistry{
		handlers:   make(map[string][]eventHandler),
		dispatcher: dispatcher,
	}
}

type eventRegistry struct {
	handlers   map[string][]eventHandler
	dispatcher func(f func())
}

func (m *eventRegistry) Subscribe(name string, handler interface{}) (unsuscribe func()) {
	if reflect.ValueOf(handler).Kind() != reflect.Func {
		panic(errors.Errorf("can't subscribe event %s: handler is not a func: %T",
			name,
			handler,
		))
	}

	id := uuid.New()

	handlers := m.handlers[name]
	handlers = append(handlers, eventHandler{
		ID:      id,
		Handler: handler,
	})
	m.handlers[name] = handlers

	return func() {
		m.Unsubscribe(name, id)
	}
}

func (m *eventRegistry) Unsubscribe(name string, id uuid.UUID) {
	handlers := m.handlers[name]

	for i, h := range handlers {
		if h.ID == id {
			end := len(handlers) - 1
			handlers[i] = handlers[end]
			handlers[end] = eventHandler{}
			handlers = handlers[:end]

			m.handlers[name] = handlers
			return
		}
	}
}

func (m *eventRegistry) Dispatch(name string, arg interface{}) {
	for _, h := range m.handlers[name] {
		val := reflect.ValueOf(h.Handler)
		typ := val.Type()

		if typ.NumIn() == 0 {
			m.dispatcher(func() {
				val.Call(nil)
			})
			return
		}

		argVal := reflect.ValueOf(arg)
		argTyp := typ.In(0)

		if !argVal.Type().ConvertibleTo(argTyp) {
			Errorf("dispatching event %s failed: can't convert %s to %s",
				name,
				argVal.Type(),
				argTyp,
			)
			return
		}

		m.dispatcher(func() {
			val.Call([]reflect.Value{
				argVal.Convert(argTyp),
			})
		})
	}
}

// EventRegistryWithLogs returns a decorated version of the given event registry
// that logs all its operations.
func EventRegistryWithLogs(r EventRegistry) EventRegistry {
	return &eventRegistryWithLogs{
		base: r,
	}
}

type eventRegistryWithLogs struct {
	base EventRegistry
}

func (r *eventRegistryWithLogs) Subscribe(name string, handler interface{}) func() {
	Logf("subscribing to event %s with %T", name, handler)
	unsuscribe := r.base.Subscribe(name, handler)

	return func() {
		Log("unsubscribing %T from event %s", handler, name)
		unsuscribe()
	}
}

func (r *eventRegistryWithLogs) Dispatch(name string, arg interface{}) {
	Logf("dispatching event %s %+v", arg)
	r.base.Dispatch(name, arg)
}

// ConcurrentEventRegistry returns a decorated version of the given event
// registry that ensure concurrency safety.
func ConcurrentEventRegistry(r EventRegistry) EventRegistry {
	return &concurrentEventRegistry{
		base: r,
	}
}

type concurrentEventRegistry struct {
	mutex sync.RWMutex
	base  EventRegistry
}

func (r *concurrentEventRegistry) Subscribe(name string, handler interface{}) func() {
	r.mutex.Lock()
	unsubscribe := r.base.Subscribe(name, handler)
	r.mutex.Unlock()

	return func() {
		r.mutex.Lock()
		unsubscribe()
		r.mutex.Unlock()
	}
}

func (r *concurrentEventRegistry) Dispatch(name string, arg interface{}) {
	r.mutex.RLock()
	r.base.Dispatch(name, arg)
	r.mutex.RUnlock()
}

// EventSubscriber is the interface that describes an event subscriber.
type EventSubscriber interface {
	// Subscribe subscribes the given handler to the named event.
	// It panics if handler is not a func.
	Subscribe(name string, handler interface{})

	// Close closes the event handler and unsubscribe all its events.
	Close()
}

// NewEventSubscriber creates an event subscriber.
func NewEventSubscriber() EventSubscriber {
	return &eventSubscriber{
		registry: DefaultEventRegistry,
	}
}

type eventSubscriber struct {
	registry    EventRegistry
	unsuscribes []func()
}

func (s *eventSubscriber) Subscribe(name string, handler interface{}) {
	unsubscribe := s.registry.Subscribe(name, handler)
	s.unsuscribes = append(s.unsuscribes, unsubscribe)
}

func (s *eventSubscriber) Close() {
	for _, unsuscribe := range s.unsuscribes {
		unsuscribe()
	}
}

// MouseEvent represents an onmouse event arg.
type MouseEvent struct {
	ClientX   float64
	ClientY   float64
	PageX     float64
	PageY     float64
	ScreenX   float64
	ScreenY   float64
	Button    int
	Detail    int
	AltKey    bool
	CtrlKey   bool
	MetaKey   bool
	ShiftKey  bool
	InnerText string
}

// WheelEvent represents an onwheel event arg.
type WheelEvent struct {
	DeltaX    float64
	DeltaY    float64
	DeltaZ    float64
	DeltaMode DeltaMode
}

// DeltaMode is an indication of the units of measurement for a delta value.
type DeltaMode uint64

// KeyboardEvent represents an onkey event arg.
type KeyboardEvent struct {
	CharCode  rune
	KeyCode   key.Code
	Location  key.Location
	AltKey    bool
	CtrlKey   bool
	MetaKey   bool
	ShiftKey  bool
	InnerText string
}

// DragAndDropEvent represents an ondrop event arg.
type DragAndDropEvent struct {
	Files         []string
	Data          string
	DropEffect    string
	EffectAllowed string
}
<commit_msg>covet<commit_after>package app

import (
	"reflect"
	"sync"

	"github.com/google/uuid"
	"github.com/murlokswarm/app/key"
	"github.com/pkg/errors"
)

var (
	// DefaultEventRegistry is the default event registry.
	DefaultEventRegistry EventRegistry
)

// EventRegistry is the interface that describes an event registry.
type EventRegistry interface {
	// Subscribe subscribes the given handler to the named event.
	// It panics if handler is not a func.
	Subscribe(name string, handler interface{}) (unsuscribe func())

	EventDispatcher
}

// EventDispatcher is the interface that describes an event dispatcher.
type EventDispatcher interface {
	// Dispatch dispatches the named event with the given argument.
	// It is done on the UI goroutine.
	Dispatch(name string, arg interface{})
}

type eventHandler struct {
	ID      uuid.UUID
	Handler interface{}
}

// NewEventRegistry creates an event registry.
func NewEventRegistry(dispatcher func(func())) EventRegistry {
	return &eventRegistry{
		handlers:   make(map[string][]eventHandler),
		dispatcher: dispatcher,
	}
}

type eventRegistry struct {
	handlers   map[string][]eventHandler
	dispatcher func(f func())
}

func (m *eventRegistry) Subscribe(name string, handler interface{}) (unsuscribe func()) {
	if reflect.ValueOf(handler).Kind() != reflect.Func {
		panic(errors.Errorf("can't subscribe event %s: handler is not a func: %T",
			name,
			handler,
		))
	}

	id := uuid.New()

	handlers := m.handlers[name]
	handlers = append(handlers, eventHandler{
		ID:      id,
		Handler: handler,
	})
	m.handlers[name] = handlers

	return func() {
		m.Unsubscribe(name, id)
	}
}

func (m *eventRegistry) Unsubscribe(name string, id uuid.UUID) {
	handlers := m.handlers[name]

	for i, h := range handlers {
		if h.ID == id {
			end := len(handlers) - 1
			handlers[i] = handlers[end]
			handlers[end] = eventHandler{}
			handlers = handlers[:end]

			m.handlers[name] = handlers
			return
		}
	}
}

func (m *eventRegistry) Dispatch(name string, arg interface{}) {
	for _, h := range m.handlers[name] {
		val := reflect.ValueOf(h.Handler)
		typ := val.Type()

		if typ.NumIn() == 0 {
			m.dispatcher(func() {
				val.Call(nil)
			})
			return
		}

		argVal := reflect.ValueOf(arg)
		argTyp := typ.In(0)

		if !argVal.Type().ConvertibleTo(argTyp) {
			Errorf("dispatching event %s failed: can't convert %s to %s",
				name,
				argVal.Type(),
				argTyp,
			)
			return
		}

		m.dispatcher(func() {
			val.Call([]reflect.Value{
				argVal.Convert(argTyp),
			})
		})
	}
}

// EventRegistryWithLogs returns a decorated version of the given event registry
// that logs all its operations.
func EventRegistryWithLogs(r EventRegistry) EventRegistry {
	return &eventRegistryWithLogs{
		base: r,
	}
}

type eventRegistryWithLogs struct {
	base EventRegistry
}

func (r *eventRegistryWithLogs) Subscribe(name string, handler interface{}) func() {
	Logf("subscribing to event %s with %T", name, handler)
	unsuscribe := r.base.Subscribe(name, handler)

	return func() {
		Logf("unsubscribing %T from event %s", handler, name)
		unsuscribe()
	}
}

func (r *eventRegistryWithLogs) Dispatch(name string, arg interface{}) {
	Logf("dispatching event %s %+v", arg)
	r.base.Dispatch(name, arg)
}

// ConcurrentEventRegistry returns a decorated version of the given event
// registry that ensure concurrency safety.
func ConcurrentEventRegistry(r EventRegistry) EventRegistry {
	return &concurrentEventRegistry{
		base: r,
	}
}

type concurrentEventRegistry struct {
	mutex sync.RWMutex
	base  EventRegistry
}

func (r *concurrentEventRegistry) Subscribe(name string, handler interface{}) func() {
	r.mutex.Lock()
	unsubscribe := r.base.Subscribe(name, handler)
	r.mutex.Unlock()

	return func() {
		r.mutex.Lock()
		unsubscribe()
		r.mutex.Unlock()
	}
}

func (r *concurrentEventRegistry) Dispatch(name string, arg interface{}) {
	r.mutex.RLock()
	r.base.Dispatch(name, arg)
	r.mutex.RUnlock()
}

// EventSubscriber is the interface that describes an event subscriber.
type EventSubscriber interface {
	// Subscribe subscribes the given handler to the named event.
	// It panics if handler is not a func.
	Subscribe(name string, handler interface{})

	// Close closes the event handler and unsubscribe all its events.
	Close()
}

// NewEventSubscriber creates an event subscriber.
func NewEventSubscriber() EventSubscriber {
	return &eventSubscriber{
		registry: DefaultEventRegistry,
	}
}

type eventSubscriber struct {
	registry    EventRegistry
	unsuscribes []func()
}

func (s *eventSubscriber) Subscribe(name string, handler interface{}) {
	unsubscribe := s.registry.Subscribe(name, handler)
	s.unsuscribes = append(s.unsuscribes, unsubscribe)
}

func (s *eventSubscriber) Close() {
	for _, unsuscribe := range s.unsuscribes {
		unsuscribe()
	}
}

// MouseEvent represents an onmouse event arg.
type MouseEvent struct {
	ClientX   float64
	ClientY   float64
	PageX     float64
	PageY     float64
	ScreenX   float64
	ScreenY   float64
	Button    int
	Detail    int
	AltKey    bool
	CtrlKey   bool
	MetaKey   bool
	ShiftKey  bool
	InnerText string
}

// WheelEvent represents an onwheel event arg.
type WheelEvent struct {
	DeltaX    float64
	DeltaY    float64
	DeltaZ    float64
	DeltaMode DeltaMode
}

// DeltaMode is an indication of the units of measurement for a delta value.
type DeltaMode uint64

// KeyboardEvent represents an onkey event arg.
type KeyboardEvent struct {
	CharCode  rune
	KeyCode   key.Code
	Location  key.Location
	AltKey    bool
	CtrlKey   bool
	MetaKey   bool
	ShiftKey  bool
	InnerText string
}

// DragAndDropEvent represents an ondrop event arg.
type DragAndDropEvent struct {
	Files         []string
	Data          string
	DropEffect    string
	EffectAllowed string
}
<|endoftext|>


<commit_before>package openapi

import (
	"reflect"
	"testing"
)

const (
	exampleCom  = "https://example.com"
	exampleMail = "foo@example.com"
)

type candidate struct {
	label  string
	in     validater
	hasErr bool
}

func testValidater(t *testing.T, candidates []candidate) {
	t.Helper()
	for _, c := range candidates {
		if err := c.in.Validate(); (err != nil) != c.hasErr {
			if c.hasErr {
				t.Error("error should be occurred, but not")
				continue
			}
			t.Errorf("error is occurred: %s", err)
		}
	}
}

func TestHasDuplicatedParameter(t *testing.T) {
	t.Run("no duplicated param", testHasDuplicatedParameterFalse)
	t.Run("there's duplicated param", testHasDuplicatedParameterTrue)
}

func testHasDuplicatedParameterFalse(t *testing.T) {
	params := []*Parameter{
		&Parameter{Name: "foo", In: "header"},
		&Parameter{Name: "foo", In: "path", Required: true},
		&Parameter{Name: "bar", In: "path", Required: true},
	}
	if hasDuplicatedParameter(params) {
		t.Error("should return false")
	}
}

func testHasDuplicatedParameterTrue(t *testing.T) {
	params := []*Parameter{
		&Parameter{Name: "foo", In: "header"},
		&Parameter{Name: "foo", In: "header"},
	}
	if !hasDuplicatedParameter(params) {
		t.Error("should return true")
	}
}

func TestMustURL(t *testing.T) {
	candidates := []struct {
		label  string
		in     string
		hasErr bool
	}{
		{"empty", "", true},
		{"valid HTTP url", "http://example.com", false},
		{"allowed relative path", "foo/bar/baz", true},
		{"absolute path", "/foo/bar/baz", false},
		{"plain string", "foobarbaz", true},
	}
	for _, c := range candidates {
		if err := mustURL(c.label, c.in); (err != nil) != c.hasErr {
			t.Logf("error occured at %s", c.label)
			if c.hasErr {
				t.Error("error should occured, but not")
				return
			}
			t.Error("error should not occurred, but occurred")
			return
		}
	}
}

func TestDocumentValidate(t *testing.T) {
	candidates := []candidate{
		{"empty", Document{}, true},
		{"withInvalidVersion", Document{Version: "1.0"}, true},
		{"withVersion", Document{Version: "3.0.0"}, true},
		{"valid", Document{Version: "3.0.0", Info: &Info{Title: "foo", TermsOfService: exampleCom, Version: "1.0"}, Paths: Paths{}}, false},
	}
	testValidater(t, candidates)
}

func TestValidateOASVersion(t *testing.T) {
	candidates := []struct {
		label  string
		in     string
		hasErr bool
	}{
		{"empty", "", true},
		{"invalidVersion", "foobar", true},
		{"swagger", "2.0", true},
		{"valid", "3.0.0", false},
	}
	for _, c := range candidates {
		if err := validateOASVersion(c.in); (err != nil) != c.hasErr {
			t.Log(c.label)
			if c.hasErr {
				t.Error("error should be occurred, but not")
				continue
			}
			t.Errorf("error should not be occured: %s", err)
		}
	}
}

func TestInfoValidate(t *testing.T) {
	candidates := []candidate{
		{"empty", Info{}, true},
	}
	testValidater(t, candidates)
}

func TestContactValidate(t *testing.T) {
	candidates := []candidate{
		{"empty", Contact{}, true},
		{"withURL", Contact{URL: exampleCom}, false},
		{"invalidURL", Contact{URL: "foobar"}, true},
		{"withEmail", Contact{Email: exampleMail}, true},
		{"valid", Contact{URL: exampleCom, Email: exampleMail}, false},
		{"invalidEmail", Contact{URL: exampleCom, Email: "foobar"}, true},
	}

	testValidater(t, candidates)
}

func TestLicenseValidate(t *testing.T) {
	candidates := []candidate{
		{"empty", License{}, true},
		{"withName", License{Name: "foobar"}, true},
		{"withURL", License{URL: exampleCom}, true},
		{"invalidURL", License{Name: "foobar", URL: "foobar"}, true},
		{"valid", License{Name: "foobar", URL: exampleCom}, false},
	}
	testValidater(t, candidates)
}

func TestServerValidate(t *testing.T) {
	candidates := []candidate{
		{"empty", Server{}, true},
		{"invalidURL", Server{URL: "foobar%"}, true},
		{"withURL", Server{URL: exampleCom}, false},
	}
	testValidater(t, candidates)
}

func TestServerVariableValidate(t *testing.T) {
	candidates := []candidate{
		{"empty", ServerVariable{}, true},
		{"withDefault", ServerVariable{Default: "default"}, false},
	}
	testValidater(t, candidates)
}

func TestComponents(t *testing.T) {
	candidates := []candidate{
		{"empty", Components{}, true},
	}
	testValidater(t, candidates)
}

func TestComponentsValidateKeys(t *testing.T) {
	candidates := []struct {
		label  string
		in     Components
		hasErr bool
	}{
		{"empty", Components{}, true},
	}
	for _, c := range candidates {
		if err := c.in.validateKeys(); (err != nil) != c.hasErr {
			t.Log(c.label)
			if c.hasErr {
				t.Error("error should be occurred, but not")
				continue
			}
			t.Errorf("error should not be occurred: %s", err)
		}
	}
}

func TestReduceComponentKeys(t *testing.T) {
	candidates := []struct {
		label    string
		in       Components
		expected []string
	}{
		{"empty", Components{}, []string{}},
	}
	for _, c := range candidates {
		keys := reduceComponentKeys(c.in)
		if !reflect.DeepEqual(keys, c.expected) {
			t.Log(c.label)
			t.Errorf("%+v != %+v", keys, c.expected)
		}
	}
}
func TestPathsValidate(t *testing.T) {
	t.Run("duplicate pathItem", testPathItemDuplicate)
}

func getPaths(id1, id2 string) Paths {
	return Paths{
		"/foo/bar": &PathItem{
			Get:  &Operation{OperationID: id1, Responses: Responses{"200": &Response{Description: "foo"}}},
			Post: &Operation{OperationID: id2, Responses: Responses{"200": &Response{Description: "foo"}}},
		},
	}
}

func testPathItemDuplicate(t *testing.T) {
	candidates := []candidate{
		{"invalid", getPaths("foobar", "foobar"), true},
		{"valid", getPaths("foo", "bar"), false},
	}
	testValidater(t, candidates)
}

func TestExternalDocumentationValidate(t *testing.T) {
	candidates := []candidate{
		{"empty", ExternalDocumentation{}, true},
		{"invalidURL", ExternalDocumentation{URL: "foobar"}, true},
		{"valid", ExternalDocumentation{URL: exampleCom}, false},
	}
	testValidater(t, candidates)
}

func TestTagValidate(t *testing.T) {
	candidates := []candidate{
		{"empty", Tag{}, true},
		{"withEmptyExternalDocs", Tag{ExternalDocs: &ExternalDocumentation{}}, true},
		{"withValidExternalDocs", Tag{ExternalDocs: &ExternalDocumentation{URL: exampleCom}}, true},

		{"withName", Tag{Name: "foo"}, false},
	}
	testValidater(t, candidates)
}

func TestSchemaValidate(t *testing.T) {
	candidates := []candidate{
		{"empty", Schema{}, false},
	}
	testValidater(t, candidates)
}

func TestDiscriminatorValidate(t *testing.T) {
	candidates := []candidate{
		{"empty", Discriminator{}, true},
		{"withPropertyName", Discriminator{PropertyName: "foobar"}, false},
	}
	testValidater(t, candidates)
}

func TestXMLValidate(t *testing.T) {
	candidates := []candidate{
		{"empty", XML{}, true},
		{"invalidURLNamespace", XML{Namespace: "foobar"}, true},
		{"withNamespace", XML{Namespace: exampleCom}, false},
	}
	testValidater(t, candidates)
}

func TestOAuthFlowValidate(t *testing.T) {
	mockScopes := map[string]string{"foo": "bar"}

	empty := OAuthFlow{}
	aURL := OAuthFlow{AuthorizationURL: exampleCom}
	tURL := OAuthFlow{TokenURL: exampleCom}
	rURL := OAuthFlow{RefreshURL: exampleCom}
	scopes := OAuthFlow{Scopes: mockScopes}
	atURL := OAuthFlow{AuthorizationURL: exampleCom, TokenURL: exampleCom}
	arURL := OAuthFlow{AuthorizationURL: exampleCom, RefreshURL: exampleCom}
	aURLscopes := OAuthFlow{AuthorizationURL: exampleCom, Scopes: mockScopes}
	trURL := OAuthFlow{TokenURL: exampleCom, RefreshURL: exampleCom}
	tURLscopes := OAuthFlow{TokenURL: exampleCom, Scopes: mockScopes}
	rURLscopes := OAuthFlow{RefreshURL: exampleCom, Scopes: mockScopes}
	atrURL := OAuthFlow{AuthorizationURL: exampleCom, TokenURL: exampleCom, RefreshURL: exampleCom}
	atURLscopes := OAuthFlow{AuthorizationURL: exampleCom, TokenURL: exampleCom, Scopes: mockScopes}
	arURLscopes := OAuthFlow{AuthorizationURL: exampleCom, RefreshURL: exampleCom, Scopes: mockScopes}
	trURLscopes := OAuthFlow{TokenURL: exampleCom, RefreshURL: exampleCom, Scopes: mockScopes}
	atrURLscopes := OAuthFlow{AuthorizationURL: exampleCom, TokenURL: exampleCom, RefreshURL: exampleCom, Scopes: mockScopes}
	invalidURL := OAuthFlow{AuthorizationURL: "foobar", TokenURL: "foobar", RefreshURL: "foobar", Scopes: mockScopes}
	zeroMap := OAuthFlow{AuthorizationURL: exampleCom, TokenURL: exampleCom, RefreshURL: exampleCom, Scopes: map[string]string{}}

	candidates := []struct {
		label   string
		in      OAuthFlow
		haveErr [4]bool
	}{
		{"empty", empty, [4]bool{true, true, true, true}},
		{"aURL", aURL, [4]bool{true, true, true, true}},
		{"tURL", tURL, [4]bool{true, true, true, true}},
		{"rURL", rURL, [4]bool{true, true, true, true}},
		{"scopes", scopes, [4]bool{true, true, true, true}},
		{"aURL/tURL", atURL, [4]bool{true, true, true, true}},
		{"aURL/rURL", arURL, [4]bool{true, true, true, true}},
		{"aURL/scopes", aURLscopes, [4]bool{false, true, true, true}},
		{"tURL/rURL", trURL, [4]bool{true, true, true, true}},
		{"tURL/scopes", tURLscopes, [4]bool{true, false, false, true}},
		{"rURL/scopes", rURLscopes, [4]bool{true, true, true, true}},
		{"aURL/tURL/rURL", atrURL, [4]bool{true, true, true, true}},
		{"aURL/tURL/scopes", atURLscopes, [4]bool{false, false, false, false}},
		{"aURL/rURL/scopes", arURLscopes, [4]bool{false, true, true, true}},
		{"tURL/rURL/scopes", trURLscopes, [4]bool{true, false, false, true}},
		{"aURL/tURL/rURL/scopes", atrURLscopes, [4]bool{false, false, false, false}},

		{"invalidURL", invalidURL, [4]bool{true, true, true, true}},
		{"zero length map", zeroMap, [4]bool{true, true, true, true}},
	}
	for _, c := range candidates {
		testOAuthFlowValidate(t, c.label, c.in, c.haveErr)
	}
}

var flowTypes = []string{"implicit", "password", "clientCredentials", "authorizationCode"}

func testOAuthFlowValidate(t *testing.T, label string, oauthFlow OAuthFlow, haveErr [4]bool) {
	if err := oauthFlow.Validate(""); err == nil {
		t.Logf("%s-empty", label)
		t.Error("error should be occurred, but not")
	}
	if err := oauthFlow.Validate("foobar"); err == nil {
		t.Logf("%s-wrongtype", label)
		t.Error("error should be occurred, but not")
	}
	for i, flowType := range flowTypes {
		if err := oauthFlow.Validate(flowType); (err != nil) != haveErr[i] {
			t.Logf("%s-%s", label, flowType)
			if haveErr[i] {
				t.Error("error should be occurred, but not")
				continue
			}
			t.Error("error should not be occurred, but occurred")
			t.Log(err)
		}
	}
}
<commit_msg>add empty test for reduceComponentObjects<commit_after>package openapi

import (
	"reflect"
	"testing"
)

const (
	exampleCom  = "https://example.com"
	exampleMail = "foo@example.com"
)

type candidate struct {
	label  string
	in     validater
	hasErr bool
}

func testValidater(t *testing.T, candidates []candidate) {
	t.Helper()
	for _, c := range candidates {
		if err := c.in.Validate(); (err != nil) != c.hasErr {
			if c.hasErr {
				t.Error("error should be occurred, but not")
				continue
			}
			t.Errorf("error is occurred: %s", err)
		}
	}
}

func TestHasDuplicatedParameter(t *testing.T) {
	t.Run("no duplicated param", testHasDuplicatedParameterFalse)
	t.Run("there's duplicated param", testHasDuplicatedParameterTrue)
}

func testHasDuplicatedParameterFalse(t *testing.T) {
	params := []*Parameter{
		&Parameter{Name: "foo", In: "header"},
		&Parameter{Name: "foo", In: "path", Required: true},
		&Parameter{Name: "bar", In: "path", Required: true},
	}
	if hasDuplicatedParameter(params) {
		t.Error("should return false")
	}
}

func testHasDuplicatedParameterTrue(t *testing.T) {
	params := []*Parameter{
		&Parameter{Name: "foo", In: "header"},
		&Parameter{Name: "foo", In: "header"},
	}
	if !hasDuplicatedParameter(params) {
		t.Error("should return true")
	}
}

func TestMustURL(t *testing.T) {
	candidates := []struct {
		label  string
		in     string
		hasErr bool
	}{
		{"empty", "", true},
		{"valid HTTP url", "http://example.com", false},
		{"allowed relative path", "foo/bar/baz", true},
		{"absolute path", "/foo/bar/baz", false},
		{"plain string", "foobarbaz", true},
	}
	for _, c := range candidates {
		if err := mustURL(c.label, c.in); (err != nil) != c.hasErr {
			t.Logf("error occured at %s", c.label)
			if c.hasErr {
				t.Error("error should occured, but not")
				return
			}
			t.Error("error should not occurred, but occurred")
			return
		}
	}
}

func TestDocumentValidate(t *testing.T) {
	candidates := []candidate{
		{"empty", Document{}, true},
		{"withInvalidVersion", Document{Version: "1.0"}, true},
		{"withVersion", Document{Version: "3.0.0"}, true},
		{"valid", Document{Version: "3.0.0", Info: &Info{Title: "foo", TermsOfService: exampleCom, Version: "1.0"}, Paths: Paths{}}, false},
	}
	testValidater(t, candidates)
}

func TestValidateOASVersion(t *testing.T) {
	candidates := []struct {
		label  string
		in     string
		hasErr bool
	}{
		{"empty", "", true},
		{"invalidVersion", "foobar", true},
		{"swagger", "2.0", true},
		{"valid", "3.0.0", false},
	}
	for _, c := range candidates {
		if err := validateOASVersion(c.in); (err != nil) != c.hasErr {
			t.Log(c.label)
			if c.hasErr {
				t.Error("error should be occurred, but not")
				continue
			}
			t.Errorf("error should not be occured: %s", err)
		}
	}
}

func TestInfoValidate(t *testing.T) {
	candidates := []candidate{
		{"empty", Info{}, true},
	}
	testValidater(t, candidates)
}

func TestContactValidate(t *testing.T) {
	candidates := []candidate{
		{"empty", Contact{}, true},
		{"withURL", Contact{URL: exampleCom}, false},
		{"invalidURL", Contact{URL: "foobar"}, true},
		{"withEmail", Contact{Email: exampleMail}, true},
		{"valid", Contact{URL: exampleCom, Email: exampleMail}, false},
		{"invalidEmail", Contact{URL: exampleCom, Email: "foobar"}, true},
	}

	testValidater(t, candidates)
}

func TestLicenseValidate(t *testing.T) {
	candidates := []candidate{
		{"empty", License{}, true},
		{"withName", License{Name: "foobar"}, true},
		{"withURL", License{URL: exampleCom}, true},
		{"invalidURL", License{Name: "foobar", URL: "foobar"}, true},
		{"valid", License{Name: "foobar", URL: exampleCom}, false},
	}
	testValidater(t, candidates)
}

func TestServerValidate(t *testing.T) {
	candidates := []candidate{
		{"empty", Server{}, true},
		{"invalidURL", Server{URL: "foobar%"}, true},
		{"withURL", Server{URL: exampleCom}, false},
	}
	testValidater(t, candidates)
}

func TestServerVariableValidate(t *testing.T) {
	candidates := []candidate{
		{"empty", ServerVariable{}, true},
		{"withDefault", ServerVariable{Default: "default"}, false},
	}
	testValidater(t, candidates)
}

func TestComponents(t *testing.T) {
	candidates := []candidate{
		{"empty", Components{}, true},
	}
	testValidater(t, candidates)
}

func TestComponentsValidateKeys(t *testing.T) {
	candidates := []struct {
		label  string
		in     Components
		hasErr bool
	}{
		{"empty", Components{}, true},
	}
	for _, c := range candidates {
		if err := c.in.validateKeys(); (err != nil) != c.hasErr {
			t.Log(c.label)
			if c.hasErr {
				t.Error("error should be occurred, but not")
				continue
			}
			t.Errorf("error should not be occurred: %s", err)
		}
	}
}

func TestReduceComponentKeys(t *testing.T) {
	candidates := []struct {
		label    string
		in       Components
		expected []string
	}{
		{"empty", Components{}, []string{}},
	}
	for _, c := range candidates {
		keys := reduceComponentKeys(c.in)
		if !reflect.DeepEqual(keys, c.expected) {
			t.Log(c.label)
			t.Errorf("%+v != %+v", keys, c.expected)
		}
	}
}

func TestReduceComponentObjects(t *testing.T) {
	candidates := []struct {
		label    string
		in       Components
		expected []validater
	}{
		{"empty", Components{}, []validater{}},
	}
	for _, c := range candidates {
		objects := reduceComponentObjects(c.in)
		if !reflect.DeepEqual(objects, c.expected) {
			t.Log(c.label)
			t.Errorf("%+v != %+v", objects, c.expected)
		}
	}
}

func TestPathsValidate(t *testing.T) {
	t.Run("duplicate pathItem", testPathItemDuplicate)
}

func getPaths(id1, id2 string) Paths {
	return Paths{
		"/foo/bar": &PathItem{
			Get:  &Operation{OperationID: id1, Responses: Responses{"200": &Response{Description: "foo"}}},
			Post: &Operation{OperationID: id2, Responses: Responses{"200": &Response{Description: "foo"}}},
		},
	}
}

func testPathItemDuplicate(t *testing.T) {
	candidates := []candidate{
		{"invalid", getPaths("foobar", "foobar"), true},
		{"valid", getPaths("foo", "bar"), false},
	}
	testValidater(t, candidates)
}

func TestExternalDocumentationValidate(t *testing.T) {
	candidates := []candidate{
		{"empty", ExternalDocumentation{}, true},
		{"invalidURL", ExternalDocumentation{URL: "foobar"}, true},
		{"valid", ExternalDocumentation{URL: exampleCom}, false},
	}
	testValidater(t, candidates)
}

func TestTagValidate(t *testing.T) {
	candidates := []candidate{
		{"empty", Tag{}, true},
		{"withEmptyExternalDocs", Tag{ExternalDocs: &ExternalDocumentation{}}, true},
		{"withValidExternalDocs", Tag{ExternalDocs: &ExternalDocumentation{URL: exampleCom}}, true},

		{"withName", Tag{Name: "foo"}, false},
	}
	testValidater(t, candidates)
}

func TestSchemaValidate(t *testing.T) {
	candidates := []candidate{
		{"empty", Schema{}, false},
	}
	testValidater(t, candidates)
}

func TestDiscriminatorValidate(t *testing.T) {
	candidates := []candidate{
		{"empty", Discriminator{}, true},
		{"withPropertyName", Discriminator{PropertyName: "foobar"}, false},
	}
	testValidater(t, candidates)
}

func TestXMLValidate(t *testing.T) {
	candidates := []candidate{
		{"empty", XML{}, true},
		{"invalidURLNamespace", XML{Namespace: "foobar"}, true},
		{"withNamespace", XML{Namespace: exampleCom}, false},
	}
	testValidater(t, candidates)
}

func TestOAuthFlowValidate(t *testing.T) {
	mockScopes := map[string]string{"foo": "bar"}

	empty := OAuthFlow{}
	aURL := OAuthFlow{AuthorizationURL: exampleCom}
	tURL := OAuthFlow{TokenURL: exampleCom}
	rURL := OAuthFlow{RefreshURL: exampleCom}
	scopes := OAuthFlow{Scopes: mockScopes}
	atURL := OAuthFlow{AuthorizationURL: exampleCom, TokenURL: exampleCom}
	arURL := OAuthFlow{AuthorizationURL: exampleCom, RefreshURL: exampleCom}
	aURLscopes := OAuthFlow{AuthorizationURL: exampleCom, Scopes: mockScopes}
	trURL := OAuthFlow{TokenURL: exampleCom, RefreshURL: exampleCom}
	tURLscopes := OAuthFlow{TokenURL: exampleCom, Scopes: mockScopes}
	rURLscopes := OAuthFlow{RefreshURL: exampleCom, Scopes: mockScopes}
	atrURL := OAuthFlow{AuthorizationURL: exampleCom, TokenURL: exampleCom, RefreshURL: exampleCom}
	atURLscopes := OAuthFlow{AuthorizationURL: exampleCom, TokenURL: exampleCom, Scopes: mockScopes}
	arURLscopes := OAuthFlow{AuthorizationURL: exampleCom, RefreshURL: exampleCom, Scopes: mockScopes}
	trURLscopes := OAuthFlow{TokenURL: exampleCom, RefreshURL: exampleCom, Scopes: mockScopes}
	atrURLscopes := OAuthFlow{AuthorizationURL: exampleCom, TokenURL: exampleCom, RefreshURL: exampleCom, Scopes: mockScopes}
	invalidURL := OAuthFlow{AuthorizationURL: "foobar", TokenURL: "foobar", RefreshURL: "foobar", Scopes: mockScopes}
	zeroMap := OAuthFlow{AuthorizationURL: exampleCom, TokenURL: exampleCom, RefreshURL: exampleCom, Scopes: map[string]string{}}

	candidates := []struct {
		label   string
		in      OAuthFlow
		haveErr [4]bool
	}{
		{"empty", empty, [4]bool{true, true, true, true}},
		{"aURL", aURL, [4]bool{true, true, true, true}},
		{"tURL", tURL, [4]bool{true, true, true, true}},
		{"rURL", rURL, [4]bool{true, true, true, true}},
		{"scopes", scopes, [4]bool{true, true, true, true}},
		{"aURL/tURL", atURL, [4]bool{true, true, true, true}},
		{"aURL/rURL", arURL, [4]bool{true, true, true, true}},
		{"aURL/scopes", aURLscopes, [4]bool{false, true, true, true}},
		{"tURL/rURL", trURL, [4]bool{true, true, true, true}},
		{"tURL/scopes", tURLscopes, [4]bool{true, false, false, true}},
		{"rURL/scopes", rURLscopes, [4]bool{true, true, true, true}},
		{"aURL/tURL/rURL", atrURL, [4]bool{true, true, true, true}},
		{"aURL/tURL/scopes", atURLscopes, [4]bool{false, false, false, false}},
		{"aURL/rURL/scopes", arURLscopes, [4]bool{false, true, true, true}},
		{"tURL/rURL/scopes", trURLscopes, [4]bool{true, false, false, true}},
		{"aURL/tURL/rURL/scopes", atrURLscopes, [4]bool{false, false, false, false}},

		{"invalidURL", invalidURL, [4]bool{true, true, true, true}},
		{"zero length map", zeroMap, [4]bool{true, true, true, true}},
	}
	for _, c := range candidates {
		testOAuthFlowValidate(t, c.label, c.in, c.haveErr)
	}
}

var flowTypes = []string{"implicit", "password", "clientCredentials", "authorizationCode"}

func testOAuthFlowValidate(t *testing.T, label string, oauthFlow OAuthFlow, haveErr [4]bool) {
	if err := oauthFlow.Validate(""); err == nil {
		t.Logf("%s-empty", label)
		t.Error("error should be occurred, but not")
	}
	if err := oauthFlow.Validate("foobar"); err == nil {
		t.Logf("%s-wrongtype", label)
		t.Error("error should be occurred, but not")
	}
	for i, flowType := range flowTypes {
		if err := oauthFlow.Validate(flowType); (err != nil) != haveErr[i] {
			t.Logf("%s-%s", label, flowType)
			if haveErr[i] {
				t.Error("error should be occurred, but not")
				continue
			}
			t.Error("error should not be occurred, but occurred")
			t.Log(err)
		}
	}
}
<|endoftext|>


<commit_before>package vue

// Vue.partial( id, [definition] )
// id String
// definition String | Node optional
// Register or retrieve a global partial.
// The definition can be a template string, a querySelector that starts with #,
// a DOM element (whose innerHTML will be used as the template string),
// or a DocumentFragment.
func Partial(name, definition string) {
	vue.Call("partial", name, definition)
}

// Defer the callback to be executed after the next DOM update cycle.
// Use it immediately after you’ve changed some data to wait for the DOM update.
func NextTick(cb func()) {
	vue.Call("nextTick", cb)
}

// Vue.set( object, key, value )
//
// Arguments:
//
//  {Object} object
//  {String} key
//  {*} value
//  Returns: the set value.
//
// Set a property on an object. If the object is reactive,
// ensure the property is created as a reactive property and
// trigger view updates. This is primarily used to get
// around the limitation that Vue cannot detect property additions.
func Set(obj, key, value interface{}) {
	vue.Call("set", obj, key, value)
}

// Vue.delete( object, key )
//
// Arguments:
//
//  {Object} object
//  {String} key
//  Usage:
//
// Delete a property on an object.
// If the object is reactive, ensure the deletion triggers view updates.
// This is primarily used to get around the limitation that
// Vue cannot detect property deletions, but you should rarely need to use it.
func Delete(obj, key interface{}) {
	vue.Call("delete", obj, key)
}
<commit_msg>add VueJS global config support<commit_after>package vue

import (
	"github.com/gopherjs/gopherjs/js"
)

// TConfig is used for declaration only
type TConfig struct {
	*js.Object
	// Suppress all Vue logs and warnings.
	Silent bool `js:"silent"`
	// The merge strategy receives the value of that option defined on the parent and child instances as the first and second arguments, respectively.
	OptionMergeStrategies interface{} `js:"optionMergeStrategies"`
	// Configure whether to allow vue-devtools inspection.
	Devtools bool `js:"devtools"`
	// Assign a handler for uncaught errors during component render and watchers.
	ErrorHandler func(err, vm *js.Object) `js:"errorHandler"`
	// Make Vue ignore custom elements defined outside of Vue (e.g., using the Web Components APIs).
	IgnoredElements []string `js:"ignoredElements"`
	// Define custom key alias(es) for v-on.
	KeyCodes map[string]int `js:"keyCodes"`
}

// Vue.partial( id, [definition] )
// id String
// definition String | Node optional
// Register or retrieve a global partial.
// The definition can be a template string, a querySelector that starts with #,
// a DOM element (whose innerHTML will be used as the template string),
// or a DocumentFragment.
func Partial(name, definition string) {
	vue.Call("partial", name, definition)
}

// Defer the callback to be executed after the next DOM update cycle.
// Use it immediately after you’ve changed some data to wait for the DOM update.
func NextTick(cb func()) {
	vue.Call("nextTick", cb)
}

// Vue.set( object, key, value )
//
// Arguments:
//
//  {Object} object
//  {String} key
//  {*} value
//  Returns: the set value.
//
// Set a property on an object. If the object is reactive,
// ensure the property is created as a reactive property and
// trigger view updates. This is primarily used to get
// around the limitation that Vue cannot detect property additions.
func Set(obj, key, value interface{}) {
	vue.Call("set", obj, key, value)
}

// Vue.delete( object, key )
//
// Arguments:
//
//  {Object} object
//  {String} key
//  Usage:
//
// Delete a property on an object.
// If the object is reactive, ensure the deletion triggers view updates.
// This is primarily used to get around the limitation that
// Vue cannot detect property deletions, but you should rarely need to use it.
func Delete(obj, key interface{}) {
	vue.Call("delete", obj, key)
}

var Config = &TConfig{}

func init() {
	Config.Object = vue.Get("config")
}
<|endoftext|>


<commit_before>package config

import (
	"context"
	"os"
	"time"

	"github.com/go-ozzo/ozzo-config"
	"github.com/joho/godotenv"
	_ "github.com/joho/godotenv/autoload"
	"github.com/juju/errors"
)

var (
	errInitiate           = "config: initiate '%s' error"
	errConfigure          = "config: configure error"
	errReload             = "config: reload error"
	errLoadFromEnvFile    = "config: load from env file error"
	errLoadFromEnv        = "config: load from env error"
	errLoadFromConfigFile = "config: load from config file error"
	errLoadFromConfigPath = "config: load from config path error"
)

type Type uint

const (
	Invalid Type = iota
	String
	Bool
	Int
	Int64
	Float64
	Time
	Duration
	StringSlice
	StringMap
	StringMapString
	StringMapStringSlice
	SizeInBytes
)

var initiated bool

type Callback func(ctx context.Context, value interface{}) (interface{}, error)

type Option struct {
	Type           Type
	Default        interface{}
	EnvironmentKey string
}

func NewConfig() *Config {
	instance := &Config{}
	return instance
}

type Config struct {
	Provider string
	handler  Handler

	options               map[string]Option
	bindedEnvironmentKeys []string
}

func (c *Config) Prepare(ctx context.Context) (context.Context, error) {
	return ctx, nil
}

func (c *Config) Initiate(ctx context.Context) (context.Context, error) {
	if initiated {
		return ctx, nil
	}
	if c.options == nil {
		c.options = make(map[string]Option)
	}
	err := Register("viper", NewViperHandler)
	if err != nil {
		return ctx, errors.Annotatef(err, errInitiate, c.Provider)
	}
	err = c.Use(ctx, "viper")
	if err != nil {
		return ctx, errors.Annotatef(err, errInitiate, c.Provider)
	}
	return ctx, nil
}
func (c *Config) OnStartup(ctx context.Context) (context.Context, error) {
	return ctx, nil
}
func (c *Config) OnShutdown(ctx context.Context) (context.Context, error) {
	return ctx, nil
}
func (c *Config) GetProvider() string {
	return c.Provider
}
func (c *Config) Use(ctx context.Context, Provider string) error {
	handler, err := Use(Provider)
	if err != nil {
		return err
	}
	c.Provider = Provider
	c.handler = handler()
	err = c.handler.Initiate(ctx)
	if err != nil {
		return errors.Annotatef(err, errInitiate, c.Provider)
	}
	return nil
}
func (c *Config) AddConfigPath(in string) {
	c.handler.AddConfigPath(in)
}
func (c *Config) ConfigFileUsed() string {
	return c.handler.ConfigFileUsed()
}
func (c *Config) SetEnvPrefix(in string) {
	c.handler.SetEnvPrefix(in)
}
func (c *Config) SetOptions(options map[string]Option) error {
	if options != nil {
		keys := make([]string, 0)
		for key, option := range options {
			if key != "" {
				if _, ok := c.options[key]; !ok {
					c.options[key] = option
				}
				keys = append(keys, key)
			}
			if option.Default != nil {
				c.handler.SetDefault(key, option.Default)
			}
		}
	}
	return nil
}
func (c *Config) Callbacks(ctx context.Context, callbacks map[string]Callback) (context.Context, error) {
	if callbacks != nil {
		for key, callback := range callbacks {
			value := c.Get(key)
			if value != nil {
				value, err := callback(ctx, value)
				if err != nil {
					return ctx, errors.Annotatef(err, "config: callback '%s' error:", key)
				}
				c.Set(key, value)
			}
		}
	}
	return ctx, nil
}

func (c *Config) ConfigureFileConfig(target interface{}, configFile string, configProviders map[string]interface{}, configTag ...string) (err error) {
	oc := config.New()
	err = oc.Load(configFile)
	if err != nil {
		return errors.Annotatef(err, "config: load config file '%s'", configFile)
	}
	if len(configProviders) > 0 {
		for configProviderName, configProvider := range configProviders {
			err = oc.Register(configProviderName, configProvider)
			if err != nil {
				return errors.Annotatef(err, "config: register config provider '%s' error", configProviderName)
			}
		}
	}
	err = oc.Configure(target, configTag...)
	if err != nil {
		return errors.Annotatef(err, "config: configure '%v' error", target)
	}
	return nil
}

func (c *Config) ConfigureJsonConfig(target interface{}, configData []byte, configProviders map[string]interface{}, configTag ...string) (err error) {
	oc := config.New()
	err = oc.LoadJSON(configData)
	if err != nil {
		return errors.Annotatef(err, "config: load config '%s' error", configData)
	}
	if len(configProviders) > 0 {
		for configProviderName, configProvider := range configProviders {
			err = oc.Register(configProviderName, configProvider)
			if err != nil {
				return errors.Annotatef(err, "config: register config provider '%s' error", configProviderName)
			}
		}
	}
	err = oc.Configure(target, configTag...)
	if err != nil {
		return errors.Annotatef(err, "config: configure '%s' error", target)
	}
	return nil
}

func (c *Config) LoadFromConfigPath(configName string) error {
	c.handler.SetConfigName(configName)
	err := c.handler.ReadInConfig()
	if err != nil {
		return errors.Annotatef(err, errLoadFromConfigPath)
	}
	return nil
}
func (c *Config) LoadFromConfigFile(configFile string) error {
	c.handler.SetConfigFile(configFile)
	err := c.handler.ReadInConfig()
	if err != nil {
		return errors.Annotatef(err, errLoadFromConfigFile)
	}
	return nil
}
func (c *Config) BindedEnvironmentKeys() []string {
	return c.bindedEnvironmentKeys
}
func (c *Config) LoadFromEnv() error {
	for key, option := range c.options {
		if option.EnvironmentKey != "" {
			err := c.handler.BindEnv(option.EnvironmentKey)
			if err != nil {
				return errors.Annotatef(err, errLoadFromEnv+": [key:'%s', env_key:'%s']", key, option.EnvironmentKey)
			}
			c.bindedEnvironmentKeys = append(c.bindedEnvironmentKeys, option.EnvironmentKey)
		}
	}
	return nil
}
func (c *Config) LoadFromEnvFile(dotEnvFile string) error {
	if dotEnvFile != "" {
		_, err := os.Stat(dotEnvFile)
		if err != nil {
			if os.IsNotExist(err) {
				return errors.Annotatef(err, errLoadFromEnvFile)
			}
		}
		err = godotenv.Load(dotEnvFile)
		if err != nil {
			return errors.Annotatef(err, errLoadFromEnvFile)
		}
		err = c.LoadFromEnv()
		if err != nil {
			return errors.Annotatef(err, errLoadFromEnvFile)
		}
	}
	return nil
}
func (c *Config) WithContextValue(ctx context.Context, keymaps map[string]string) {
	if c.options != nil {
		for key, option := range c.options {
			contextKey := key
			if _, ok := keymaps[key]; ok {
				contextKey = keymaps[key]
			}
			switch option.Type {
			case String:
				ctx = context.WithValue(ctx, contextKey, c.GetString(key))
			case Bool:
				ctx = context.WithValue(ctx, contextKey, c.GetBool(key))
			case Int:
				ctx = context.WithValue(ctx, contextKey, c.GetInt(key))
			case Int64:
				ctx = context.WithValue(ctx, contextKey, c.GetInt64(key))
			case Float64:
				ctx = context.WithValue(ctx, contextKey, c.GetFloat64(key))
			case Time:
				ctx = context.WithValue(ctx, contextKey, c.GetTime(key))
			case Duration:
				ctx = context.WithValue(ctx, contextKey, c.GetDuration(key))
			case StringSlice:
				ctx = context.WithValue(ctx, contextKey, c.GetStringSlice(key))
			case StringMap:
				ctx = context.WithValue(ctx, contextKey, c.GetStringMap(key))
			case StringMapString:
				ctx = context.WithValue(ctx, contextKey, c.GetStringMapString(key))
			case StringMapStringSlice:
				ctx = context.WithValue(ctx, contextKey, c.GetStringMapStringSlice(key))
			case SizeInBytes:
				ctx = context.WithValue(ctx, contextKey, c.GetSizeInBytes(key))
			}
		}
	}
}
func (c *Config) Set(key string, value interface{}) {
	c.handler.Set(key, value)
}

// GetString returns the value associated with the key as a string.
func (c *Config) Get(key string) interface{} {
	return c.handler.Get(key)
}

// GetString returns the value associated with the key as a string.
func (c *Config) GetString(key string) string {
	return c.handler.GetString(key)
}

// GetBool returns the value associated with the key as a boolean.
func (c *Config) GetBool(key string) bool {
	return c.handler.GetBool(key)
}

// GetInt returns the value associated with the key as an integer.
func (c *Config) GetInt(key string) int {
	return c.handler.GetInt(key)
}

// GetInt64 returns the value associated with the key as an integer.
func (c *Config) GetInt64(key string) int64 {
	return c.handler.GetInt64(key)
}

// GetFloat64 returns the value associated with the key as a float64.
func (c *Config) GetFloat64(key string) float64 {
	return c.handler.GetFloat64(key)
}

// GetTime returns the value associated with the key as time.
func (c *Config) GetTime(key string) time.Time {
	return c.handler.GetTime(key)
}

// GetDuration returns the value associated with the key as a duration.
func (c *Config) GetDuration(key string) time.Duration {
	return c.handler.GetDuration(key)
}

// GetStringSlice returns the value associated with the key as a slice of strings.
func (c *Config) GetStringSlice(key string) []string {
	return c.handler.GetStringSlice(key)
}

// GetStringMap returns the value associated with the key as a map of interfaces.
func (c *Config) GetStringMap(key string) map[string]interface{} {
	return c.handler.GetStringMap(key)
}

// GetStringMapString returns the value associated with the key as a map of strings.
func (c *Config) GetStringMapString(key string) map[string]string {
	return c.handler.GetStringMapString(key)
}

// GetStringMapStringSlice returns the value associated with the key as a map to a slice of strings.
func (c *Config) GetStringMapStringSlice(key string) map[string][]string {
	return c.handler.GetStringMapStringSlice(key)
}

// GetSizeInBytes returns the size of the value associated with the given key
// in bytes.
func (c *Config) GetSizeInBytes(key string) uint {
	return c.handler.GetSizeInBytes(key)
}

type configHandler func() Handler

var configHandlers = make(map[string]configHandler)

func Register(name string, configHandler configHandler) error {
	if configHandler == nil {
		return errors.New("config: Register config is nil")
	}
	if _, ok := configHandlers[name]; !ok {
		configHandlers[name] = configHandler
	}
	return nil
}
func Use(name string) (configHandler, error) {
	if _, exist := configHandlers[name]; !exist {
		return nil, errors.New("config: unknown config " + name + " (forgotten register?)")
	}
	return configHandlers[name], nil
}

type Handler interface {
	Initiate(ctx context.Context) error
	AddConfigPath(in string)
	SetConfigName(in string)
	SetConfigFile(in string)
	ConfigFileUsed() string
	SetDefault(key string, value interface{})
	BindEnv(in string) error
	SetEnvPrefix(in string)
	ReadInConfig() error
	AllSettings() map[string]interface{}
	Set(key string, value interface{})
	Get(key string) interface{}
	// GetString returns the value associated with the key as a string.
	GetString(key string) string
	// GetBool returns the value associated with the key as a boolean.
	GetBool(key string) bool
	// GetInt returns the value associated with the key as an integer.
	GetInt(key string) int
	// GetInt64 returns the value associated with the key as an integer.
	GetInt64(key string) int64
	// GetFloat64 returns the value associated with the key as a float64.
	GetFloat64(key string) float64
	// GetTime returns the value associated with the key as time.
	GetTime(key string) time.Time
	// GetDuration returns the value associated with the key as a duration.
	GetDuration(key string) time.Duration
	// GetStringSlice returns the value associated with the key as a slice of strings.
	GetStringSlice(key string) []string
	// GetStringMap returns the value associated with the key as a map of interfaces.
	GetStringMap(key string) map[string]interface{}
	// GetStringMapString returns the value associated with the key as a map of strings.
	GetStringMapString(key string) map[string]string
	// GetStringMapStringSlice returns the value associated with the key as a map to a slice of strings.
	GetStringMapStringSlice(key string) map[string][]string
	// GetSizeInBytes returns the size of the value associated with the given key
	// in bytes.
	GetSizeInBytes(key string) uint
}
<commit_msg>config模块<commit_after>package config

import (
	"context"
	"os"
	"time"

	"github.com/go-ozzo/ozzo-config"
	"github.com/joho/godotenv"
	_ "github.com/joho/godotenv/autoload"
	"github.com/juju/errors"
)

var (
	errInitiate           = "config: initiate '%s' error"
	errConfigure          = "config: configure error"
	errReload             = "config: reload error"
	errLoadFromEnvFile    = "config: load from env file error"
	errLoadFromEnv        = "config: load from env error"
	errLoadFromConfigFile = "config: load from config file error"
	errLoadFromConfigPath = "config: load from config path error"
)

type Type uint

const (
	Invalid Type = iota
	String
	Bool
	Int
	Int64
	Float64
	Time
	Duration
	StringSlice
	StringMap
	StringMapString
	StringMapStringSlice
	SizeInBytes
)

type Callback func(ctx context.Context, value interface{}) (interface{}, error)

type Option struct {
	Type           Type
	Default        interface{}
	EnvironmentKey string
}

func NewConfig() *Config {
	instance := &Config{}
	return instance
}

type Config struct {
	Provider string
	handler  Handler

	options               map[string]Option
	bindedEnvironmentKeys []string
}

func (c *Config) Prepare(ctx context.Context) (context.Context, error) {
	return ctx, nil
}

func (c *Config) Initiate(ctx context.Context) (context.Context, error) {
	if c.options == nil {
		c.options = make(map[string]Option)
	}
	err := Register("viper", NewViperHandler)
	if err != nil {
		return ctx, errors.Annotatef(err, errInitiate, c.Provider)
	}
	err = c.Use(ctx, "viper")
	if err != nil {
		return ctx, errors.Annotatef(err, errInitiate, c.Provider)
	}
	return ctx, nil
}
func (c *Config) OnStartup(ctx context.Context) (context.Context, error) {
	return ctx, nil
}
func (c *Config) OnShutdown(ctx context.Context) (context.Context, error) {
	return ctx, nil
}
func (c *Config) GetProvider() string {
	return c.Provider
}
func (c *Config) Use(ctx context.Context, Provider string) error {
	handler, err := Use(Provider)
	if err != nil {
		return err
	}
	c.Provider = Provider
	c.handler = handler()
	err = c.handler.Initiate(ctx)
	if err != nil {
		return errors.Annotatef(err, errInitiate, c.Provider)
	}
	return nil
}
func (c *Config) AddConfigPath(in string) {
	c.handler.AddConfigPath(in)
}
func (c *Config) ConfigFileUsed() string {
	return c.handler.ConfigFileUsed()
}
func (c *Config) SetEnvPrefix(in string) {
	c.handler.SetEnvPrefix(in)
}
func (c *Config) SetOptions(options map[string]Option) error {
	if options != nil {
		keys := make([]string, 0)
		for key, option := range options {
			if key != "" {
				if _, ok := c.options[key]; !ok {
					c.options[key] = option
				}
				keys = append(keys, key)
			}
			if option.Default != nil {
				c.handler.SetDefault(key, option.Default)
			}
		}
	}
	return nil
}
func (c *Config) Callbacks(ctx context.Context, callbacks map[string]Callback) (context.Context, error) {
	if callbacks != nil {
		for key, callback := range callbacks {
			value := c.Get(key)
			if value != nil {
				value, err := callback(ctx, value)
				if err != nil {
					return ctx, errors.Annotatef(err, "config: callback '%s' error:", key)
				}
				c.Set(key, value)
			}
		}
	}
	return ctx, nil
}

func (c *Config) ConfigureFileConfig(target interface{}, configFile string, configProviders map[string]interface{}, configTag ...string) (err error) {
	oc := config.New()
	err = oc.Load(configFile)
	if err != nil {
		return errors.Annotatef(err, "config: load config file '%s'", configFile)
	}
	if len(configProviders) > 0 {
		for configProviderName, configProvider := range configProviders {
			err = oc.Register(configProviderName, configProvider)
			if err != nil {
				return errors.Annotatef(err, "config: register config provider '%s' error", configProviderName)
			}
		}
	}
	err = oc.Configure(target, configTag...)
	if err != nil {
		return errors.Annotatef(err, "config: configure '%v' error", target)
	}
	return nil
}

func (c *Config) ConfigureJsonConfig(target interface{}, configData []byte, configProviders map[string]interface{}, configTag ...string) (err error) {
	oc := config.New()
	err = oc.LoadJSON(configData)
	if err != nil {
		return errors.Annotatef(err, "config: load config '%s' error", configData)
	}
	if len(configProviders) > 0 {
		for configProviderName, configProvider := range configProviders {
			err = oc.Register(configProviderName, configProvider)
			if err != nil {
				return errors.Annotatef(err, "config: register config provider '%s' error", configProviderName)
			}
		}
	}
	err = oc.Configure(target, configTag...)
	if err != nil {
		return errors.Annotatef(err, "config: configure '%s' error", target)
	}
	return nil
}

func (c *Config) LoadFromConfigPath(configName string) error {
	c.handler.SetConfigName(configName)
	err := c.handler.ReadInConfig()
	if err != nil {
		return errors.Annotatef(err, errLoadFromConfigPath)
	}
	return nil
}
func (c *Config) LoadFromConfigFile(configFile string) error {
	c.handler.SetConfigFile(configFile)
	err := c.handler.ReadInConfig()
	if err != nil {
		return errors.Annotatef(err, errLoadFromConfigFile)
	}
	return nil
}
func (c *Config) BindedEnvironmentKeys() []string {
	return c.bindedEnvironmentKeys
}
func (c *Config) LoadFromEnv() error {
	for key, option := range c.options {
		if option.EnvironmentKey != "" {
			err := c.handler.BindEnv(option.EnvironmentKey)
			if err != nil {
				return errors.Annotatef(err, errLoadFromEnv+": [key:'%s', env_key:'%s']", key, option.EnvironmentKey)
			}
			c.bindedEnvironmentKeys = append(c.bindedEnvironmentKeys, option.EnvironmentKey)
		}
	}
	return nil
}
func (c *Config) LoadFromEnvFile(dotEnvFile string) error {
	if dotEnvFile != "" {
		_, err := os.Stat(dotEnvFile)
		if err != nil {
			if os.IsNotExist(err) {
				return errors.Annotatef(err, errLoadFromEnvFile)
			}
		}
		err = godotenv.Load(dotEnvFile)
		if err != nil {
			return errors.Annotatef(err, errLoadFromEnvFile)
		}
		err = c.LoadFromEnv()
		if err != nil {
			return errors.Annotatef(err, errLoadFromEnvFile)
		}
	}
	return nil
}
func (c *Config) WithContextValue(ctx context.Context, keymaps map[string]string) {
	if c.options != nil {
		for key, option := range c.options {
			contextKey := key
			if _, ok := keymaps[key]; ok {
				contextKey = keymaps[key]
			}
			switch option.Type {
			case String:
				ctx = context.WithValue(ctx, contextKey, c.GetString(key))
			case Bool:
				ctx = context.WithValue(ctx, contextKey, c.GetBool(key))
			case Int:
				ctx = context.WithValue(ctx, contextKey, c.GetInt(key))
			case Int64:
				ctx = context.WithValue(ctx, contextKey, c.GetInt64(key))
			case Float64:
				ctx = context.WithValue(ctx, contextKey, c.GetFloat64(key))
			case Time:
				ctx = context.WithValue(ctx, contextKey, c.GetTime(key))
			case Duration:
				ctx = context.WithValue(ctx, contextKey, c.GetDuration(key))
			case StringSlice:
				ctx = context.WithValue(ctx, contextKey, c.GetStringSlice(key))
			case StringMap:
				ctx = context.WithValue(ctx, contextKey, c.GetStringMap(key))
			case StringMapString:
				ctx = context.WithValue(ctx, contextKey, c.GetStringMapString(key))
			case StringMapStringSlice:
				ctx = context.WithValue(ctx, contextKey, c.GetStringMapStringSlice(key))
			case SizeInBytes:
				ctx = context.WithValue(ctx, contextKey, c.GetSizeInBytes(key))
			}
		}
	}
}
func (c *Config) Set(key string, value interface{}) {
	c.handler.Set(key, value)
}

// GetString returns the value associated with the key as a string.
func (c *Config) Get(key string) interface{} {
	return c.handler.Get(key)
}

// GetString returns the value associated with the key as a string.
func (c *Config) GetString(key string) string {
	return c.handler.GetString(key)
}

// GetBool returns the value associated with the key as a boolean.
func (c *Config) GetBool(key string) bool {
	return c.handler.GetBool(key)
}

// GetInt returns the value associated with the key as an integer.
func (c *Config) GetInt(key string) int {
	return c.handler.GetInt(key)
}

// GetInt64 returns the value associated with the key as an integer.
func (c *Config) GetInt64(key string) int64 {
	return c.handler.GetInt64(key)
}

// GetFloat64 returns the value associated with the key as a float64.
func (c *Config) GetFloat64(key string) float64 {
	return c.handler.GetFloat64(key)
}

// GetTime returns the value associated with the key as time.
func (c *Config) GetTime(key string) time.Time {
	return c.handler.GetTime(key)
}

// GetDuration returns the value associated with the key as a duration.
func (c *Config) GetDuration(key string) time.Duration {
	return c.handler.GetDuration(key)
}

// GetStringSlice returns the value associated with the key as a slice of strings.
func (c *Config) GetStringSlice(key string) []string {
	return c.handler.GetStringSlice(key)
}

// GetStringMap returns the value associated with the key as a map of interfaces.
func (c *Config) GetStringMap(key string) map[string]interface{} {
	return c.handler.GetStringMap(key)
}

// GetStringMapString returns the value associated with the key as a map of strings.
func (c *Config) GetStringMapString(key string) map[string]string {
	return c.handler.GetStringMapString(key)
}

// GetStringMapStringSlice returns the value associated with the key as a map to a slice of strings.
func (c *Config) GetStringMapStringSlice(key string) map[string][]string {
	return c.handler.GetStringMapStringSlice(key)
}

// GetSizeInBytes returns the size of the value associated with the given key
// in bytes.
func (c *Config) GetSizeInBytes(key string) uint {
	return c.handler.GetSizeInBytes(key)
}

type configHandler func() Handler

var configHandlers = make(map[string]configHandler)

func Register(name string, configHandler configHandler) error {
	if configHandler == nil {
		return errors.New("config: Register config is nil")
	}
	if _, ok := configHandlers[name]; !ok {
		configHandlers[name] = configHandler
	}
	return nil
}
func Use(name string) (configHandler, error) {
	if _, exist := configHandlers[name]; !exist {
		return nil, errors.New("config: unknown config " + name + " (forgotten register?)")
	}
	return configHandlers[name], nil
}

type Handler interface {
	Initiate(ctx context.Context) error
	AddConfigPath(in string)
	SetConfigName(in string)
	SetConfigFile(in string)
	ConfigFileUsed() string
	SetDefault(key string, value interface{})
	BindEnv(in string) error
	SetEnvPrefix(in string)
	ReadInConfig() error
	AllSettings() map[string]interface{}
	Set(key string, value interface{})
	Get(key string) interface{}
	// GetString returns the value associated with the key as a string.
	GetString(key string) string
	// GetBool returns the value associated with the key as a boolean.
	GetBool(key string) bool
	// GetInt returns the value associated with the key as an integer.
	GetInt(key string) int
	// GetInt64 returns the value associated with the key as an integer.
	GetInt64(key string) int64
	// GetFloat64 returns the value associated with the key as a float64.
	GetFloat64(key string) float64
	// GetTime returns the value associated with the key as time.
	GetTime(key string) time.Time
	// GetDuration returns the value associated with the key as a duration.
	GetDuration(key string) time.Duration
	// GetStringSlice returns the value associated with the key as a slice of strings.
	GetStringSlice(key string) []string
	// GetStringMap returns the value associated with the key as a map of interfaces.
	GetStringMap(key string) map[string]interface{}
	// GetStringMapString returns the value associated with the key as a map of strings.
	GetStringMapString(key string) map[string]string
	// GetStringMapStringSlice returns the value associated with the key as a map to a slice of strings.
	GetStringMapStringSlice(key string) map[string][]string
	// GetSizeInBytes returns the size of the value associated with the given key
	// in bytes.
	GetSizeInBytes(key string) uint
}
<|endoftext|>