<commit_before>package dockerclient

import (
	"bytes"
	"crypto/tls"
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"net/url"
	"sync/atomic"
)

var (
	ErrNotFound = errors.New("Not found")
)

type DockerClient struct {
	URL           *url.URL
	HTTPClient    *http.Client
	monitorEvents int32
}

type Callback func(*Event, ...interface{})

type Error struct {
	StatusCode int
	Status     string
	msg        string
}

func (e Error) Error() string {
	return fmt.Sprintf("%s: %s", e.Status, e.msg)
}

func NewDockerClient(daemonUrl string, tlsConfig *tls.Config) (*DockerClient, error) {
	u, err := url.Parse(daemonUrl)
	if err != nil {
		return nil, err
	}
	if u.Scheme == "tcp" {
		u.Scheme = "http"
	}
	httpClient := newHTTPClient(u, tlsConfig)
	return &DockerClient{u, httpClient, 0}, nil
}

func (client *DockerClient) doRequest(method string, path string, body []byte) ([]byte, error) {
	b := bytes.NewBuffer(body)
	req, err := http.NewRequest(method, client.URL.String()+path, b)
	if err != nil {
		return nil, err
	}
	req.Header.Add("Content-Type", "application/json")
	resp, err := client.HTTPClient.Do(req)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()
	data, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}
	if resp.StatusCode == 404 {
		return nil, ErrNotFound
	}
	if resp.StatusCode >= 400 {
		return nil, Error{StatusCode: resp.StatusCode, Status: resp.Status, msg: string(data)}
	}
	return data, nil
}

func (client *DockerClient) Info() (*Info, error) {
	data, err := client.doRequest("GET", "/v1.10/info", nil)
	if err != nil {
		return nil, err
	}
	ret := &Info{}
	err = json.Unmarshal(data, &ret)
	if err != nil {
		return nil, err
	}
	return ret, nil
}

func (client *DockerClient) ListContainers(all bool) ([]Container, error) {
	argAll := 0
	if all == true {
		argAll = 1
	}
	args := fmt.Sprintf("?all=%d", argAll)
	data, err := client.doRequest("GET", "/v1.10/containers/json"+args, nil)
	if err != nil {
		return nil, err
	}
	ret := []Container{}
	err = json.Unmarshal(data, &ret)
	if err != nil {
		return nil, err
	}
	return ret, nil
}

func (client *DockerClient) InspectContainer(id string) (*ContainerInfo, error) {
	uri := fmt.Sprintf("/v1.10/containers/%s/json", id)
	data, err := client.doRequest("GET", uri, nil)
	if err != nil {
		return nil, err
	}
	info := &ContainerInfo{}
	err = json.Unmarshal(data, info)
	if err != nil {
		return nil, err
	}
	return info, nil
}

func (client *DockerClient) CreateContainer(config *ContainerConfig, name string) (string, error) {
	data, err := json.Marshal(config)
	if err != nil {
		return "", err
	}
	uri := "/v1.10/containers/create"

	if name != "" {
		v := url.Values{}
		v.Set("name", name)
		uri = fmt.Sprintf("%s?%s", uri, v.Encode())
	}
	data, err = client.doRequest("POST", uri, data)
	if err != nil {
		return "", err
	}
	result := &RespContainersCreate{}
	err = json.Unmarshal(data, result)
	if err != nil {
		return "", err
	}
	return result.Id, nil
}

func (client *DockerClient) ContainerLogs(id string, stdout bool, stderr bool) ([]byte, error) {
	v := url.Values{}
	if stdout {
		v.Add("stdout", "1")
	}
	if stderr {
		v.Add("stderr", "1")
	}
	uri := fmt.Sprintf("/v1.10/containers/%s/logs?%s", id, v.Encode())
	data, err := client.doRequest("GET", uri, nil)
	if err != nil {
		return nil, err
	}
	return data, nil
}

func (client *DockerClient) StartContainer(id string, config *HostConfig) error {
	data, err := json.Marshal(config)
	if err != nil {
		return err
	}
	uri := fmt.Sprintf("/v1.10/containers/%s/start", id)
	_, err = client.doRequest("POST", uri, data)
	if err != nil {
		return err
	}
	return nil
}

func (client *DockerClient) StopContainer(id string, timeout int) error {
	uri := fmt.Sprintf("/v1.10/containers/%s/stop?t=%d", id, timeout)
	_, err := client.doRequest("POST", uri, nil)
	if err != nil {
		return err
	}
	return nil
}

func (client *DockerClient) RestartContainer(id string, timeout int) error {
	uri := fmt.Sprintf("/v1.10/containers/%s/restart?t=%d", id, timeout)
	_, err := client.doRequest("POST", uri, nil)
	if err != nil {
		return err
	}
	return nil
}

func (client *DockerClient) KillContainer(id string) error {
	uri := fmt.Sprintf("/v1.10/containers/%s/kill", id)
	_, err := client.doRequest("POST", uri, nil)
	if err != nil {
		return err
	}
	return nil
}

func (client *DockerClient) StartMonitorEvents(cb Callback, args ...interface{}) {
	atomic.StoreInt32(&client.monitorEvents, 1)
	go client.getEvents(cb, args...)
}

func (client *DockerClient) getEvents(cb Callback, args ...interface{}) {
	uri := client.URL.String() + "/v1.10/events"
	resp, err := client.HTTPClient.Get(uri)
	if err != nil {
		log.Printf("GET %s failed: %v", uri, err)
		return
	}
	defer resp.Body.Close()

	dec := json.NewDecoder(resp.Body)
	for atomic.LoadInt32(&client.monitorEvents) > 0 {
		var event *Event
		if err := dec.Decode(&event); err != nil {
			log.Printf("Event decoding failed: %v", err)
			return
		}
		cb(event, args...)
	}
}

func (client *DockerClient) StopAllMonitorEvents() {
	atomic.StoreInt32(&client.monitorEvents, 0)
}

func (client *DockerClient) Version() (*Version, error) {
	data, err := client.doRequest("GET", "/v1.10/version", nil)
	if err != nil {
		return nil, err
	}
	version := &Version{}
	err = json.Unmarshal(data, version)
	if err != nil {
		return nil, err
	}
	return version, nil
}

func (client *DockerClient) PullImage(name, tag string) error {
	v := url.Values{}
	v.Set("fromImage", name)
	if tag != "" {
		v.Set("tag", tag)
	}
	_, err := client.doRequest("POST", "/v1.10/images/create?"+v.Encode(), nil)
	return err
}

func (client *DockerClient) RemoveContainer(id string, force bool) error {
	argForce := 0
	if force == true {
		argForce = 1
	}
	args := fmt.Sprintf("force=%d", argForce)

	_, err := client.doRequest("DELETE", fmt.Sprintf("/v1.10/containers/%s?%s", id, args), nil)
	return err
}

func (client *DockerClient) ListImages() ([]*Image, error) {
	data, err := client.doRequest("GET", "/v1.10/images/json", nil)
	if err != nil {
		return nil, err
	}

	var images []*Image
	if err := json.Unmarshal(data, &images); err != nil {
		return nil, err
	}

	return images, nil
}

func (client *DockerClient) RemoveImage(name string) error {
	_, err := client.doRequest("DELETE", fmt.Sprintf("/v1.10/images/%s", name), nil)
	return err
}
<commit_msg>use reader for logs<commit_after>package dockerclient

import (
	"bytes"
	"crypto/tls"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"net/url"
	"sync/atomic"
)

var (
	ErrNotFound = errors.New("Not found")
)

type DockerClient struct {
	URL           *url.URL
	HTTPClient    *http.Client
	monitorEvents int32
}

type Callback func(*Event, ...interface{})

type Error struct {
	StatusCode int
	Status     string
	msg        string
}

func (e Error) Error() string {
	return fmt.Sprintf("%s: %s", e.Status, e.msg)
}

func NewDockerClient(daemonUrl string, tlsConfig *tls.Config) (*DockerClient, error) {
	u, err := url.Parse(daemonUrl)
	if err != nil {
		return nil, err
	}
	if u.Scheme == "tcp" {
		u.Scheme = "http"
	}
	httpClient := newHTTPClient(u, tlsConfig)
	return &DockerClient{u, httpClient, 0}, nil
}

func (client *DockerClient) doRequest(method string, path string, body []byte) ([]byte, error) {
	b := bytes.NewBuffer(body)
	req, err := http.NewRequest(method, client.URL.String()+path, b)
	if err != nil {
		return nil, err
	}
	req.Header.Add("Content-Type", "application/json")
	resp, err := client.HTTPClient.Do(req)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()
	data, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}
	if resp.StatusCode == 404 {
		return nil, ErrNotFound
	}
	if resp.StatusCode >= 400 {
		return nil, Error{StatusCode: resp.StatusCode, Status: resp.Status, msg: string(data)}
	}
	return data, nil
}

func (client *DockerClient) Info() (*Info, error) {
	data, err := client.doRequest("GET", "/v1.10/info", nil)
	if err != nil {
		return nil, err
	}
	ret := &Info{}
	err = json.Unmarshal(data, &ret)
	if err != nil {
		return nil, err
	}
	return ret, nil
}

func (client *DockerClient) ListContainers(all bool) ([]Container, error) {
	argAll := 0
	if all == true {
		argAll = 1
	}
	args := fmt.Sprintf("?all=%d", argAll)
	data, err := client.doRequest("GET", "/v1.10/containers/json"+args, nil)
	if err != nil {
		return nil, err
	}
	ret := []Container{}
	err = json.Unmarshal(data, &ret)
	if err != nil {
		return nil, err
	}
	return ret, nil
}

func (client *DockerClient) InspectContainer(id string) (*ContainerInfo, error) {
	uri := fmt.Sprintf("/v1.10/containers/%s/json", id)
	data, err := client.doRequest("GET", uri, nil)
	if err != nil {
		return nil, err
	}
	info := &ContainerInfo{}
	err = json.Unmarshal(data, info)
	if err != nil {
		return nil, err
	}
	return info, nil
}

func (client *DockerClient) CreateContainer(config *ContainerConfig, name string) (string, error) {
	data, err := json.Marshal(config)
	if err != nil {
		return "", err
	}
	uri := "/v1.10/containers/create"

	if name != "" {
		v := url.Values{}
		v.Set("name", name)
		uri = fmt.Sprintf("%s?%s", uri, v.Encode())
	}
	data, err = client.doRequest("POST", uri, data)
	if err != nil {
		return "", err
	}
	result := &RespContainersCreate{}
	err = json.Unmarshal(data, result)
	if err != nil {
		return "", err
	}
	return result.Id, nil
}

func (client *DockerClient) ContainerLogs(id string, stdout bool, stderr bool) (io.ReadCloser, error) {
	v := url.Values{}
	if stdout {
		v.Add("stdout", "1")
	}
	if stderr {
		v.Add("stderr", "1")
	}
	uri := fmt.Sprintf("/v1.10/containers/%s/logs?%s", id, v.Encode())
	req, err := http.NewRequest("GET", client.URL.String()+uri, nil)
	if err != nil {
		return nil, err
	}
	req.Header.Add("Content-Type", "application/json")
	resp, err := client.HTTPClient.Do(req)
	if err != nil {
		return nil, err
	}
	return resp.Body, nil
}

func (client *DockerClient) StartContainer(id string, config *HostConfig) error {
	data, err := json.Marshal(config)
	if err != nil {
		return err
	}
	uri := fmt.Sprintf("/v1.10/containers/%s/start", id)
	_, err = client.doRequest("POST", uri, data)
	if err != nil {
		return err
	}
	return nil
}

func (client *DockerClient) StopContainer(id string, timeout int) error {
	uri := fmt.Sprintf("/v1.10/containers/%s/stop?t=%d", id, timeout)
	_, err := client.doRequest("POST", uri, nil)
	if err != nil {
		return err
	}
	return nil
}

func (client *DockerClient) RestartContainer(id string, timeout int) error {
	uri := fmt.Sprintf("/v1.10/containers/%s/restart?t=%d", id, timeout)
	_, err := client.doRequest("POST", uri, nil)
	if err != nil {
		return err
	}
	return nil
}

func (client *DockerClient) KillContainer(id string) error {
	uri := fmt.Sprintf("/v1.10/containers/%s/kill", id)
	_, err := client.doRequest("POST", uri, nil)
	if err != nil {
		return err
	}
	return nil
}

func (client *DockerClient) StartMonitorEvents(cb Callback, args ...interface{}) {
	atomic.StoreInt32(&client.monitorEvents, 1)
	go client.getEvents(cb, args...)
}

func (client *DockerClient) getEvents(cb Callback, args ...interface{}) {
	uri := client.URL.String() + "/v1.10/events"
	resp, err := client.HTTPClient.Get(uri)
	if err != nil {
		log.Printf("GET %s failed: %v", uri, err)
		return
	}
	defer resp.Body.Close()

	dec := json.NewDecoder(resp.Body)
	for atomic.LoadInt32(&client.monitorEvents) > 0 {
		var event *Event
		if err := dec.Decode(&event); err != nil {
			log.Printf("Event decoding failed: %v", err)
			return
		}
		cb(event, args...)
	}
}

func (client *DockerClient) StopAllMonitorEvents() {
	atomic.StoreInt32(&client.monitorEvents, 0)
}

func (client *DockerClient) Version() (*Version, error) {
	data, err := client.doRequest("GET", "/v1.10/version", nil)
	if err != nil {
		return nil, err
	}
	version := &Version{}
	err = json.Unmarshal(data, version)
	if err != nil {
		return nil, err
	}
	return version, nil
}

func (client *DockerClient) PullImage(name, tag string) error {
	v := url.Values{}
	v.Set("fromImage", name)
	if tag != "" {
		v.Set("tag", tag)
	}
	_, err := client.doRequest("POST", "/v1.10/images/create?"+v.Encode(), nil)
	return err
}

func (client *DockerClient) RemoveContainer(id string, force bool) error {
	argForce := 0
	if force == true {
		argForce = 1
	}
	args := fmt.Sprintf("force=%d", argForce)

	_, err := client.doRequest("DELETE", fmt.Sprintf("/v1.10/containers/%s?%s", id, args), nil)
	return err
}

func (client *DockerClient) ListImages() ([]*Image, error) {
	data, err := client.doRequest("GET", "/v1.10/images/json", nil)
	if err != nil {
		return nil, err
	}

	var images []*Image
	if err := json.Unmarshal(data, &images); err != nil {
		return nil, err
	}

	return images, nil
}

func (client *DockerClient) RemoveImage(name string) error {
	_, err := client.doRequest("DELETE", fmt.Sprintf("/v1.10/images/%s", name), nil)
	return err
}
<|endoftext|>


<commit_before>package openapi3

import (
	"context"
	"errors"
	"fmt"
	"strconv"

	"github.com/getkin/kin-openapi/jsoninfo"
	"github.com/go-openapi/jsonpointer"
)

// Responses is specified by OpenAPI/Swagger 3.0 standard.
type Responses map[string]*ResponseRef

var _ jsonpointer.JSONPointable = (*Responses)(nil)

func NewResponses() Responses {
	r := make(Responses)
	r["default"] = &ResponseRef{Value: NewResponse().WithDescription("")}
	return r
}

func (responses Responses) Default() *ResponseRef {
	return responses["default"]
}

func (responses Responses) Get(status int) *ResponseRef {
	return responses[strconv.FormatInt(int64(status), 10)]
}

func (value Responses) Validate(ctx context.Context) error {
	if len(value) == 0 {
		return errors.New("the responses object MUST contain at least one response code")
	}
	for _, v := range value {
		if err := v.Validate(ctx); err != nil {
			return err
		}
	}
	return nil
}

func (responses Responses) JSONLookup(token string) (interface{}, error) {
	ref, ok := responses[token]
	if ok == false {
		return nil, fmt.Errorf("invalid token reference: %q", token)
	}

	if ref != nil && ref.Ref != "" {
		return &Ref{Ref: ref.Ref}, nil
	}
	return ref.Value, nil
}

// Response is specified by OpenAPI/Swagger 3.0 standard.
type Response struct {
	ExtensionProps
	Description *string `json:"description,omitempty" yaml:"description,omitempty"`
	Headers     Headers `json:"headers,omitempty" yaml:"headers,omitempty"`
	Content     Content `json:"content,omitempty" yaml:"content,omitempty"`
	Links       Links   `json:"links,omitempty" yaml:"links,omitempty"`
}

func NewResponse() *Response {
	return &Response{}
}

func (response *Response) WithDescription(value string) *Response {
	response.Description = &value
	return response
}

func (response *Response) WithContent(content Content) *Response {
	response.Content = content
	return response
}

func (response *Response) WithJSONSchema(schema *Schema) *Response {
	response.Content = NewContentWithJSONSchema(schema)
	return response
}

func (response *Response) WithJSONSchemaRef(schema *SchemaRef) *Response {
	response.Content = NewContentWithJSONSchemaRef(schema)
	return response
}

func (response *Response) MarshalJSON() ([]byte, error) {
	return jsoninfo.MarshalStrictStruct(response)
}

func (response *Response) UnmarshalJSON(data []byte) error {
	return jsoninfo.UnmarshalStrictStruct(data, response)
}

func (value *Response) Validate(ctx context.Context) error {
	if value.Description == nil {
		return errors.New("a short description of the response is required")
	}

	if content := value.Content; content != nil {
		if err := content.Validate(ctx); err != nil {
			return err
		}
	}
	return nil
}
<commit_msg>Check response headers and links (#505)<commit_after>package openapi3

import (
	"context"
	"errors"
	"fmt"
	"strconv"

	"github.com/getkin/kin-openapi/jsoninfo"
	"github.com/go-openapi/jsonpointer"
)

// Responses is specified by OpenAPI/Swagger 3.0 standard.
type Responses map[string]*ResponseRef

var _ jsonpointer.JSONPointable = (*Responses)(nil)

func NewResponses() Responses {
	r := make(Responses)
	r["default"] = &ResponseRef{Value: NewResponse().WithDescription("")}
	return r
}

func (responses Responses) Default() *ResponseRef {
	return responses["default"]
}

func (responses Responses) Get(status int) *ResponseRef {
	return responses[strconv.FormatInt(int64(status), 10)]
}

func (value Responses) Validate(ctx context.Context) error {
	if len(value) == 0 {
		return errors.New("the responses object MUST contain at least one response code")
	}
	for _, v := range value {
		if err := v.Validate(ctx); err != nil {
			return err
		}
	}
	return nil
}

func (responses Responses) JSONLookup(token string) (interface{}, error) {
	ref, ok := responses[token]
	if ok == false {
		return nil, fmt.Errorf("invalid token reference: %q", token)
	}

	if ref != nil && ref.Ref != "" {
		return &Ref{Ref: ref.Ref}, nil
	}
	return ref.Value, nil
}

// Response is specified by OpenAPI/Swagger 3.0 standard.
type Response struct {
	ExtensionProps
	Description *string `json:"description,omitempty" yaml:"description,omitempty"`
	Headers     Headers `json:"headers,omitempty" yaml:"headers,omitempty"`
	Content     Content `json:"content,omitempty" yaml:"content,omitempty"`
	Links       Links   `json:"links,omitempty" yaml:"links,omitempty"`
}

func NewResponse() *Response {
	return &Response{}
}

func (response *Response) WithDescription(value string) *Response {
	response.Description = &value
	return response
}

func (response *Response) WithContent(content Content) *Response {
	response.Content = content
	return response
}

func (response *Response) WithJSONSchema(schema *Schema) *Response {
	response.Content = NewContentWithJSONSchema(schema)
	return response
}

func (response *Response) WithJSONSchemaRef(schema *SchemaRef) *Response {
	response.Content = NewContentWithJSONSchemaRef(schema)
	return response
}

func (response *Response) MarshalJSON() ([]byte, error) {
	return jsoninfo.MarshalStrictStruct(response)
}

func (response *Response) UnmarshalJSON(data []byte) error {
	return jsoninfo.UnmarshalStrictStruct(data, response)
}

func (value *Response) Validate(ctx context.Context) error {
	if value.Description == nil {
		return errors.New("a short description of the response is required")
	}

	if content := value.Content; content != nil {
		if err := content.Validate(ctx); err != nil {
			return err
		}
	}
	if headers := value.Headers; headers != nil {
		for _, header := range headers {
			if err := header.Validate(ctx); err != nil {
				return err
			}
		}
	}

	if links := value.Links; links != nil {
		for _, link := range links {
			if err := link.Validate(ctx); err != nil {
				return err
			}
		}
	}
	return nil
}
<|endoftext|>


<commit_before>package operations

import (
	"encoding/json"

	"github.com/omise/omise-go/internal"
)

// Example: Create source
//
//	source, createSource := &omise.Source{}, &CreateSource{
//		Amount:   100000,
//		Currency: "thb",
//		Type:     "bill_payment_tesco_lotus",
//	}
//	if e := client.Do(source, createSource); e != nil {
//		panic(e)
//	}
//
//	fmt.Println("created source:", source.ID)
//
type CreateSource struct {
	Type     string
	Amount   int64
	Currency string
}

func (req *CreateSource) MarshalJSON() ([]byte, error) {
	param := struct {
		Type     string `json:"type"`
		Amount   int64  `json:"amount"`
		Currency string `json:"currency"`
	}{
		Type:     req.Type,
		Amount:   req.Amount,
		Currency: req.Currency,
	}

	return json.Marshal(param)
}

func (req *CreateSource) Op() *internal.Op {
	return &internal.Op{
		Endpoint:    internal.API,
		Method:      "POST",
		Path:        "/sources",
		ContentType: "application/json",
		APIKey:      "public",
	}
}

// Example: Retrieve Source
//
//	source, retrieve := &omise.Source{}, &RetrieveSource{"src_123"}
//	if e := client.Do(source, retrieve); e != nil {
//		panic(e)
//	}
//
//	fmt.Printf("source #123: %#v\n", source)
//
type RetrieveSource struct {
	SourceID string `query:"-"`
}

func (req *RetrieveSource) Op() *internal.Op {
	return &internal.Op{
		Endpoint: internal.API,
		Method:   "GET",
		Path:     "/sources/" + req.SourceID,
	}
}
<commit_msg>Use type conversion because it's identical type<commit_after>package operations

import (
	"encoding/json"

	"github.com/omise/omise-go/internal"
)

// Example: Create source
//
//	source, createSource := &omise.Source{}, &CreateSource{
//		Amount:   100000,
//		Currency: "thb",
//		Type:     "bill_payment_tesco_lotus",
//	}
//	if e := client.Do(source, createSource); e != nil {
//		panic(e)
//	}
//
//	fmt.Println("created source:", source.ID)
//
type CreateSource struct {
	Type     string
	Amount   int64
	Currency string
}

func (req *CreateSource) MarshalJSON() ([]byte, error) {
	param := struct {
		Type     string `json:"type"`
		Amount   int64  `json:"amount"`
		Currency string `json:"currency"`
	}(*req)

	return json.Marshal(param)
}

func (req *CreateSource) Op() *internal.Op {
	return &internal.Op{
		Endpoint:    internal.API,
		Method:      "POST",
		Path:        "/sources",
		ContentType: "application/json",
		APIKey:      "public",
	}
}

// Example: Retrieve Source
//
//	source, retrieve := &omise.Source{}, &RetrieveSource{"src_123"}
//	if e := client.Do(source, retrieve); e != nil {
//		panic(e)
//	}
//
//	fmt.Printf("source #123: %#v\n", source)
//
type RetrieveSource struct {
	SourceID string `query:"-"`
}

func (req *RetrieveSource) Op() *internal.Op {
	return &internal.Op{
		Endpoint: internal.API,
		Method:   "GET",
		Path:     "/sources/" + req.SourceID,
	}
}
<|endoftext|>


<commit_before>package organization

import (
	"fmt"
	"strings"

	"github.com/pivotalservices/cf-mgmt/cloudcontroller"
	"github.com/pivotalservices/cf-mgmt/ldap"
	"github.com/pivotalservices/cf-mgmt/uaac"
	"github.com/pivotalservices/cf-mgmt/utils"
	"github.com/xchapter7x/lo"
)

//NewManager -
func NewManager(sysDomain, token, uaacToken string) (mgr Manager) {
	return &DefaultOrgManager{
		UAACMgr:         uaac.NewManager(sysDomain, uaacToken),
		CloudController: cloudcontroller.NewManager(fmt.Sprintf("https://api.%s", sysDomain), token),
		UtilsMgr:        utils.NewDefaultManager(),
		LdapMgr:         ldap.NewManager(),
	}
}

func (m *DefaultOrgManager) GetOrgConfigs(configDir string) ([]*InputUpdateOrgs, error) {
	orgConfigs := []*InputUpdateOrgs{}
	if files, err := m.UtilsMgr.FindFiles(configDir, "orgConfig.yml"); err != nil {
		return nil, err
	} else {
		for _, f := range files {
			input := &InputUpdateOrgs{}
			if err = m.UtilsMgr.LoadFile(f, input); err == nil {
				orgConfigs = append(orgConfigs, input)
			} else {
				lo.G.Error(err)
				return nil, err
			}
		}
	}
	return orgConfigs, nil
}

//CreateQuotas -
func (m *DefaultOrgManager) CreateQuotas(configDir string) error {
	var quotas map[string]string
	var org *cloudcontroller.Org
	var targetQuotaGUID string
	var orgs []*InputUpdateOrgs
	var err error
	if orgs, err = m.GetOrgConfigs(configDir); err != nil {
		return err
	}
	if quotas, err = m.CloudController.ListQuotas(); err != nil {
		return err
	}
	for _, input := range orgs {
		if input.EnableOrgQuota {
			if org, err = m.FindOrg(input.Org); err != nil {
				return err
			} else {
				quotaName := org.Entity.Name
				if quotaGUID, ok := quotas[quotaName]; ok {
					lo.G.Info("Updating quota", quotaName)
					if err = m.CloudController.UpdateQuota(quotaGUID, quotaName, input.MemoryLimit, input.InstanceMemoryLimit, input.TotalRoutes, input.TotalServices, input.PaidServicePlansAllowed); err == nil {
						lo.G.Info("Assigning", quotaName, "to", org.Entity.Name)
						if err := m.CloudController.AssignQuotaToOrg(org.MetaData.GUID, quotaGUID); err != nil {
							return err
						}
					} else {
						return err
					}
				} else {
					lo.G.Info("Creating quota", quotaName)
					if targetQuotaGUID, err = m.CloudController.CreateQuota(quotaName, input.MemoryLimit, input.InstanceMemoryLimit, input.TotalRoutes, input.TotalServices, input.PaidServicePlansAllowed); err == nil {
						lo.G.Info("Assigning", quotaName, "to", org.Entity.Name)
						if err := m.CloudController.AssignQuotaToOrg(org.MetaData.GUID, targetQuotaGUID); err != nil {
							return err
						}
					} else {
						return err
					}
				}
			}
		}
	}
	return nil
}

func (m *DefaultOrgManager) GetOrgGUID(orgName string) (string, error) {
	if org, err := m.FindOrg(orgName); err == nil {
		return org.MetaData.GUID, nil
	} else {
		return "", err
	}
}

//CreateOrgs -
func (m *DefaultOrgManager) CreateOrgs(configDir string) error {
	var configFile = configDir + "/orgs.yml"
	lo.G.Info("Processing org file", configFile)
	input := &InputOrgs{}
	if err := m.UtilsMgr.LoadFile(configFile, input); err != nil {
		return err
	}
	if orgs, err := m.CloudController.ListOrgs(); err == nil {
		for _, orgName := range input.Orgs {
			if m.DoesOrgExist(orgName, orgs) {
				lo.G.Info(fmt.Sprintf("[%s] org already exists", orgName))
			} else {
				lo.G.Info(fmt.Sprintf("Creating [%s] org", orgName))
				if err := m.CloudController.CreateOrg(orgName); err != nil {
					return err
				}
			}
		}
	} else {
		return err
	}

	return nil
}

func (m *DefaultOrgManager) DoesOrgExist(orgName string, orgs []*cloudcontroller.Org) bool {
	for _, org := range orgs {
		if org.Entity.Name == orgName {
			return true
		}
	}
	return false

}

//FindOrg -
func (m *DefaultOrgManager) FindOrg(orgName string) (*cloudcontroller.Org, error) {
	if orgs, err := m.CloudController.ListOrgs(); err == nil {
		for _, theOrg := range orgs {
			if theOrg.Entity.Name == orgName {
				return theOrg, nil
			}
		}
		return nil, fmt.Errorf("Org named[%s] not found", orgName)
	} else {
		return nil, err
	}
}

//UpdateOrgUsers -
func (m *DefaultOrgManager) UpdateOrgUsers(configDir, ldapBindPassword string) (err error) {
	var org *cloudcontroller.Org
	var config *ldap.Config
	var orgs []*InputUpdateOrgs
	if orgs, err = m.GetOrgConfigs(configDir); err != nil {
		return err
	}
	if config, err = m.LdapMgr.GetConfig(configDir, ldapBindPassword); err != nil {
		return
	}

	var uaacUsers map[string]string
	if uaacUsers, err = m.UAACMgr.ListUsers(); err != nil {
		return
	}

	if config.Enabled {
		for _, input := range orgs {
			if org, err = m.FindOrg(input.Org); err == nil {
				lo.G.Info("User sync for org", input.Org)
				if err = m.UpdateBillingManagers(config, org, input, uaacUsers); err != nil {
					return err
				}
				if err = m.UpdateManagers(config, org, input, uaacUsers); err != nil {
					return err
				}
				if err = m.UpdateAuditors(config, org, input, uaacUsers); err != nil {
					return err
				}
			}
		}
	}
	return
}

func (m *DefaultOrgManager) UpdateBillingManagers(config *ldap.Config, org *cloudcontroller.Org, input *InputUpdateOrgs, uaacUsers map[string]string) error {
	if users, err := m.getLdapUsers(config, input.GetBillingManagerGroup(), input.BillingManager.LdapUser); err == nil {
		if err = m.updateLdapUsers(config, org, "billing_managers", uaacUsers, users); err != nil {
			return err
		}
		for _, userID := range input.BillingManager.Users {
			if err := m.addUserToOrgAndRole(userID, org.MetaData.GUID, "billing_managers"); err != nil {
				return err
			}
		}
	} else {
		return err
	}
	return nil
}

func (m *DefaultOrgManager) UpdateManagers(config *ldap.Config, org *cloudcontroller.Org, input *InputUpdateOrgs, uaacUsers map[string]string) error {
	if users, err := m.getLdapUsers(config, input.GetManagerGroup(), input.Manager.LdapUser); err == nil {
		if err = m.updateLdapUsers(config, org, "managers", uaacUsers, users); err != nil {
			return err
		}
		for _, userID := range input.Manager.Users {
			if err := m.addUserToOrgAndRole(userID, org.MetaData.GUID, "managers"); err != nil {
				return err
			}
		}
	} else {
		return err
	}
	return nil
}

func (m *DefaultOrgManager) UpdateAuditors(config *ldap.Config, org *cloudcontroller.Org, input *InputUpdateOrgs, uaacUsers map[string]string) error {
	if users, err := m.getLdapUsers(config, input.GetAuditorGroup(), input.Auditor.LdapUser); err == nil {
		if err = m.updateLdapUsers(config, org, "auditors", uaacUsers, users); err != nil {
			return err
		}
		for _, userID := range input.Auditor.Users {
			if err := m.addUserToOrgAndRole(userID, org.MetaData.GUID, "auditors"); err != nil {
				return err
			}
		}
	} else {
		return err
	}
	return nil
}

func (m *DefaultOrgManager) getLdapUsers(config *ldap.Config, groupName string, userList []string) ([]ldap.User, error) {
	users := []ldap.User{}
	if groupName != "" {
		if groupUsers, err := m.LdapMgr.GetUserIDs(config, groupName); err == nil {
			users = append(users, groupUsers...)
		}
	}
	for _, user := range userList {
		if ldapUser, err := m.LdapMgr.GetUser(config, user); err == nil {
			if ldapUser != nil {
				users = append(users, *ldapUser)
			}
		} else {
			return nil, err
		}
	}
	return users, nil
}

func (m *DefaultOrgManager) updateLdapUsers(config *ldap.Config, org *cloudcontroller.Org, role string, uaacUsers map[string]string, users []ldap.User) error {
	for _, user := range users {
		if _, userExists := uaacUsers[strings.ToLower(user.UserID)]; userExists {
			lo.G.Info("User", user.UserID, "already exists")
		} else {
			lo.G.Info("User", user.UserID, "doesn't exist so creating in UAA")
			if err := m.UAACMgr.CreateLdapUser(user.UserID, user.Email, user.UserDN); err != nil {
				return err
			} else {
				uaacUsers[user.UserID] = user.UserID
			}
		}
		if err := m.addUserToOrgAndRole(user.UserID, org.MetaData.GUID, role); err != nil {
			return err
		}
	}

	return nil
}

func (m *DefaultOrgManager) addUserToOrgAndRole(userID, orgGUID, role string) error {
	lo.G.Info("Adding user to groups")
	if err := m.CloudController.AddUserToOrg(userID, orgGUID); err != nil {
		return err
	}
	if err := m.CloudController.AddUserToOrgRole(userID, role, orgGUID); err != nil {
		return err
	}
	return nil
}

func (m *DefaultOrgManager) updateUsers(config *ldap.Config, org *cloudcontroller.Org, role, groupName string, uaacUsers map[string]string) (err error) {
	var groupUsers []ldap.User

	if groupName != "" {
		lo.G.Info("Getting users for group", groupName)
		if groupUsers, err = m.LdapMgr.GetUserIDs(config, groupName); err == nil {
			for _, groupUser := range groupUsers {
				if _, userExists := uaacUsers[strings.ToLower(groupUser.UserID)]; userExists {
					lo.G.Info("User", groupUser.UserID, "already exists")
				} else {
					lo.G.Info("User", groupUser.UserID, "doesn't exist so creating in UAA")
					if err = m.UAACMgr.CreateLdapUser(groupUser.UserID, groupUser.Email, groupUser.UserDN); err != nil {
						return
					} else {
						uaacUsers[groupUser.UserID] = groupUser.UserID
					}
				}
				lo.G.Info("Adding user to groups")
				orgGUID := org.MetaData.GUID
				userName := groupUser.UserID
				if err = m.CloudController.AddUserToOrg(userName, orgGUID); err != nil {
					return
				}
				lo.G.Info("Adding", userName, "to", org.Entity.Name, "with role", role)
				err = m.CloudController.AddUserToOrgRole(userName, role, orgGUID)
				return
			}

		}
	}
	return
}
<commit_msg>remove updateUsers function from organization package, since it is not used any more<commit_after>package organization

import (
	"fmt"
	"strings"

	"github.com/pivotalservices/cf-mgmt/cloudcontroller"
	"github.com/pivotalservices/cf-mgmt/ldap"
	"github.com/pivotalservices/cf-mgmt/uaac"
	"github.com/pivotalservices/cf-mgmt/utils"
	"github.com/xchapter7x/lo"
)

//NewManager -
func NewManager(sysDomain, token, uaacToken string) (mgr Manager) {
	return &DefaultOrgManager{
		UAACMgr:         uaac.NewManager(sysDomain, uaacToken),
		CloudController: cloudcontroller.NewManager(fmt.Sprintf("https://api.%s", sysDomain), token),
		UtilsMgr:        utils.NewDefaultManager(),
		LdapMgr:         ldap.NewManager(),
	}
}

func (m *DefaultOrgManager) GetOrgConfigs(configDir string) ([]*InputUpdateOrgs, error) {
	orgConfigs := []*InputUpdateOrgs{}
	if files, err := m.UtilsMgr.FindFiles(configDir, "orgConfig.yml"); err != nil {
		return nil, err
	} else {
		for _, f := range files {
			input := &InputUpdateOrgs{}
			if err = m.UtilsMgr.LoadFile(f, input); err == nil {
				orgConfigs = append(orgConfigs, input)
			} else {
				lo.G.Error(err)
				return nil, err
			}
		}
	}
	return orgConfigs, nil
}

//CreateQuotas -
func (m *DefaultOrgManager) CreateQuotas(configDir string) error {
	var quotas map[string]string
	var org *cloudcontroller.Org
	var targetQuotaGUID string
	var orgs []*InputUpdateOrgs
	var err error
	if orgs, err = m.GetOrgConfigs(configDir); err != nil {
		return err
	}
	if quotas, err = m.CloudController.ListQuotas(); err != nil {
		return err
	}
	for _, input := range orgs {
		if input.EnableOrgQuota {
			if org, err = m.FindOrg(input.Org); err != nil {
				return err
			} else {
				quotaName := org.Entity.Name
				if quotaGUID, ok := quotas[quotaName]; ok {
					lo.G.Info("Updating quota", quotaName)
					if err = m.CloudController.UpdateQuota(quotaGUID, quotaName, input.MemoryLimit, input.InstanceMemoryLimit, input.TotalRoutes, input.TotalServices, input.PaidServicePlansAllowed); err == nil {
						lo.G.Info("Assigning", quotaName, "to", org.Entity.Name)
						if err := m.CloudController.AssignQuotaToOrg(org.MetaData.GUID, quotaGUID); err != nil {
							return err
						}
					} else {
						return err
					}
				} else {
					lo.G.Info("Creating quota", quotaName)
					if targetQuotaGUID, err = m.CloudController.CreateQuota(quotaName, input.MemoryLimit, input.InstanceMemoryLimit, input.TotalRoutes, input.TotalServices, input.PaidServicePlansAllowed); err == nil {
						lo.G.Info("Assigning", quotaName, "to", org.Entity.Name)
						if err := m.CloudController.AssignQuotaToOrg(org.MetaData.GUID, targetQuotaGUID); err != nil {
							return err
						}
					} else {
						return err
					}
				}
			}
		}
	}
	return nil
}

func (m *DefaultOrgManager) GetOrgGUID(orgName string) (string, error) {
	if org, err := m.FindOrg(orgName); err == nil {
		return org.MetaData.GUID, nil
	} else {
		return "", err
	}
}

//CreateOrgs -
func (m *DefaultOrgManager) CreateOrgs(configDir string) error {
	var configFile = configDir + "/orgs.yml"
	lo.G.Info("Processing org file", configFile)
	input := &InputOrgs{}
	if err := m.UtilsMgr.LoadFile(configFile, input); err != nil {
		return err
	}
	if orgs, err := m.CloudController.ListOrgs(); err == nil {
		for _, orgName := range input.Orgs {
			if m.DoesOrgExist(orgName, orgs) {
				lo.G.Info(fmt.Sprintf("[%s] org already exists", orgName))
			} else {
				lo.G.Info(fmt.Sprintf("Creating [%s] org", orgName))
				if err := m.CloudController.CreateOrg(orgName); err != nil {
					return err
				}
			}
		}
	} else {
		return err
	}

	return nil
}

func (m *DefaultOrgManager) DoesOrgExist(orgName string, orgs []*cloudcontroller.Org) bool {
	for _, org := range orgs {
		if org.Entity.Name == orgName {
			return true
		}
	}
	return false

}

//FindOrg -
func (m *DefaultOrgManager) FindOrg(orgName string) (*cloudcontroller.Org, error) {
	if orgs, err := m.CloudController.ListOrgs(); err == nil {
		for _, theOrg := range orgs {
			if theOrg.Entity.Name == orgName {
				return theOrg, nil
			}
		}
		return nil, fmt.Errorf("Org named[%s] not found", orgName)
	} else {
		return nil, err
	}
}

//UpdateOrgUsers -
func (m *DefaultOrgManager) UpdateOrgUsers(configDir, ldapBindPassword string) (err error) {
	var org *cloudcontroller.Org
	var config *ldap.Config
	var orgs []*InputUpdateOrgs
	if orgs, err = m.GetOrgConfigs(configDir); err != nil {
		return err
	}
	if config, err = m.LdapMgr.GetConfig(configDir, ldapBindPassword); err != nil {
		return
	}

	var uaacUsers map[string]string
	if uaacUsers, err = m.UAACMgr.ListUsers(); err != nil {
		return
	}

	if config.Enabled {
		for _, input := range orgs {
			if org, err = m.FindOrg(input.Org); err == nil {
				lo.G.Info("User sync for org", input.Org)
				if err = m.UpdateBillingManagers(config, org, input, uaacUsers); err != nil {
					return err
				}
				if err = m.UpdateManagers(config, org, input, uaacUsers); err != nil {
					return err
				}
				if err = m.UpdateAuditors(config, org, input, uaacUsers); err != nil {
					return err
				}
			}
		}
	}
	return
}

func (m *DefaultOrgManager) UpdateBillingManagers(config *ldap.Config, org *cloudcontroller.Org, input *InputUpdateOrgs, uaacUsers map[string]string) error {
	if users, err := m.getLdapUsers(config, input.GetBillingManagerGroup(), input.BillingManager.LdapUser); err == nil {
		if err = m.updateLdapUsers(config, org, "billing_managers", uaacUsers, users); err != nil {
			return err
		}
		for _, userID := range input.BillingManager.Users {
			if err := m.addUserToOrgAndRole(userID, org.MetaData.GUID, "billing_managers"); err != nil {
				return err
			}
		}
	} else {
		return err
	}
	return nil
}

func (m *DefaultOrgManager) UpdateManagers(config *ldap.Config, org *cloudcontroller.Org, input *InputUpdateOrgs, uaacUsers map[string]string) error {
	if users, err := m.getLdapUsers(config, input.GetManagerGroup(), input.Manager.LdapUser); err == nil {
		if err = m.updateLdapUsers(config, org, "managers", uaacUsers, users); err != nil {
			return err
		}
		for _, userID := range input.Manager.Users {
			if err := m.addUserToOrgAndRole(userID, org.MetaData.GUID, "managers"); err != nil {
				return err
			}
		}
	} else {
		return err
	}
	return nil
}

func (m *DefaultOrgManager) UpdateAuditors(config *ldap.Config, org *cloudcontroller.Org, input *InputUpdateOrgs, uaacUsers map[string]string) error {
	if users, err := m.getLdapUsers(config, input.GetAuditorGroup(), input.Auditor.LdapUser); err == nil {
		if err = m.updateLdapUsers(config, org, "auditors", uaacUsers, users); err != nil {
			return err
		}
		for _, userID := range input.Auditor.Users {
			if err := m.addUserToOrgAndRole(userID, org.MetaData.GUID, "auditors"); err != nil {
				return err
			}
		}
	} else {
		return err
	}
	return nil
}

func (m *DefaultOrgManager) getLdapUsers(config *ldap.Config, groupName string, userList []string) ([]ldap.User, error) {
	users := []ldap.User{}
	if groupName != "" {
		if groupUsers, err := m.LdapMgr.GetUserIDs(config, groupName); err == nil {
			users = append(users, groupUsers...)
		}
	}
	for _, user := range userList {
		if ldapUser, err := m.LdapMgr.GetUser(config, user); err == nil {
			if ldapUser != nil {
				users = append(users, *ldapUser)
			}
		} else {
			return nil, err
		}
	}
	return users, nil
}

func (m *DefaultOrgManager) updateLdapUsers(config *ldap.Config, org *cloudcontroller.Org, role string, uaacUsers map[string]string, users []ldap.User) error {
	for _, user := range users {
		if _, userExists := uaacUsers[strings.ToLower(user.UserID)]; userExists {
			lo.G.Info("User", user.UserID, "already exists")
		} else {
			lo.G.Info("User", user.UserID, "doesn't exist so creating in UAA")
			if err := m.UAACMgr.CreateLdapUser(user.UserID, user.Email, user.UserDN); err != nil {
				return err
			} else {
				uaacUsers[user.UserID] = user.UserID
			}
		}
		if err := m.addUserToOrgAndRole(user.UserID, org.MetaData.GUID, role); err != nil {
			return err
		}
	}

	return nil
}

func (m *DefaultOrgManager) addUserToOrgAndRole(userID, orgGUID, role string) error {
	lo.G.Info("Adding user to groups")
	if err := m.CloudController.AddUserToOrg(userID, orgGUID); err != nil {
		return err
	}
	if err := m.CloudController.AddUserToOrgRole(userID, role, orgGUID); err != nil {
		return err
	}
	return nil
}
<|endoftext|>


<commit_before>// Copyright 2015 Peter Goetz
//
// 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 pegomock

import (
	"reflect"
	"testing"

	"github.com/petergtz/pegomock/pegomock/internal/testingtsupport"
	"github.com/petergtz/pegomock/pegomock/types"
)

var GlobalFailHandler types.FailHandler

func RegisterMockFailHandler(handler types.FailHandler) {
	GlobalFailHandler = handler
}
func RegisterMockTestingT(t *testing.T) {
	RegisterMockFailHandler(testingtsupport.BuildTestingTGomegaFailHandler(t))
}

type Mock interface{}
type Param interface{}
type ReturnValue interface{}
type ReturnValues []ReturnValue

var lastInvocation *invocation
var argMatchers Matchers

type invocation struct {
	genericMock *GenericMock
	MethodName  string
	Params      []Param
}

type GenericMock struct {
	mockedMethods map[string]*mockedMethod
}

func (genericMock *GenericMock) Invoke(methodName string, params ...Param) ReturnValues {
	lastInvocation = &invocation{
		genericMock: genericMock,
		MethodName:  methodName,
		Params:      params,
	}
	return genericMock.getMockedMethod(methodName).Invoke(params)
}

func (genericMock *GenericMock) stub(methodName string, paramMatchers []Matcher, returnValues ReturnValues) {
	genericMock.getMockedMethod(methodName).stub(paramMatchers, returnValues)
}

func (genericMock *GenericMock) getMockedMethod(methodName string) *mockedMethod {
	if _, ok := genericMock.mockedMethods[methodName]; !ok {
		genericMock.mockedMethods[methodName] = &mockedMethod{name: methodName}
	}
	return genericMock.mockedMethods[methodName]
}

func (genericMock *GenericMock) Reset(methodName string, params []Matcher) {
	// TODO: should be called from When
}

func (genericMock *GenericMock) NumMethodInvocations(methodName string, params ...Param) int {
	if len(argMatchers) != 0 {
		checkArgument(len(argMatchers) == len(params),
			"If you use matchers, you must use matchers for all parameters. Example: TODO")
		result := genericMock.numMethodInvocationsUsingMatchers(methodName, argMatchers)
		argMatchers = nil
		return result
	}

	count := 0
	for _, invocation := range genericMock.mockedMethods[methodName].invocations {
		if reflect.DeepEqual(params, invocation) {
			count++
		}
	}
	return count
}

func (genericMock *GenericMock) numMethodInvocationsUsingMatchers(methodName string, paramMatchers Matchers) int {
	count := 0
	for _, invocation := range genericMock.mockedMethods[methodName].invocations {
		if paramMatchers.matches(invocation) {
			count++
		}
	}
	return count
}

type mockedMethod struct {
	name        string
	invocations [][]Param
	stubbings   Stubbings
}

func (method *mockedMethod) Invoke(params []Param) ReturnValues {
	method.invocations = append(method.invocations, params)
	stubbing := method.stubbings.find(params)
	if stubbing == nil {
		return ReturnValues{}
	}
	return stubbing.Invoke(params)
}

func (method *mockedMethod) stub(paramMatchers Matchers, returnValues ReturnValues) {
	stubbing := method.stubbings.findByMatchers(paramMatchers)
	if stubbing != nil {
		stubbing.returnValuesSequence = append(stubbing.returnValuesSequence, returnValues)
	} else {
		method.stubbings = append(method.stubbings, &Stubbing{
			paramMatchers:        paramMatchers,
			returnValuesSequence: []ReturnValues{returnValues},
		})
	}
}

func (method *mockedMethod) removeLastInvocation() {
	method.invocations = method.invocations[:len(method.invocations)-1]
}

type Stubbings []*Stubbing

func (stubbings Stubbings) find(params []Param) *Stubbing {
	for _, stubbing := range stubbings {
		if stubbing.paramMatchers.matches(params) {
			return stubbing
		}
	}
	return nil
}

func (stubbings Stubbings) findByMatchers(paramMatchers Matchers) *Stubbing {
	for _, stubbing := range stubbings {
		if reflect.DeepEqual(stubbing.paramMatchers, paramMatchers) {
			return stubbing
		}
	}
	return nil
}

type Stubbing struct {
	paramMatchers        Matchers
	returnValuesSequence []ReturnValues
	sequencePointer      int
}

func (stubbing *Stubbing) Invoke(params []Param) ReturnValues {
	result := stubbing.returnValuesSequence[stubbing.sequencePointer]
	if stubbing.sequencePointer < len(stubbing.returnValuesSequence)-1 {
		stubbing.sequencePointer++
	}
	return result
}

type Matchers []Matcher

func (matchers Matchers) matches(params []Param) bool {
	checkArgument(len(matchers) == len(params),
		"Number of params and matchers different: params: %v, matchers: %v",
		params, matchers)
	for i := range params {
		if !matchers[i].matches(params[i]) {
			return false
		}
	}
	return true
}

func (matchers *Matchers) append(matcher Matcher) {
	*matchers = append(*matchers, matcher)
}

type ongoingStubbing struct {
	genericMock   *GenericMock
	MethodName    string
	ParamMatchers []Matcher
	returnValues  []interface{}
}

func When(invocation ...interface{}) *ongoingStubbing {
	checkNotNil(lastInvocation,
		"when() requires an argument which has to be 'a method call on a mock'.")
	defer func() {
		lastInvocation = nil
		argMatchers = nil
	}()
	lastInvocation.genericMock.mockedMethods[lastInvocation.MethodName].removeLastInvocation()
	return &ongoingStubbing{
		genericMock:   lastInvocation.genericMock,
		MethodName:    lastInvocation.MethodName,
		ParamMatchers: paramMatchersFromArgMatchersOrParams(argMatchers, lastInvocation.Params),
		returnValues:  invocation,
	}
}

func paramMatchersFromArgMatchersOrParams(argMatchers []Matcher, params []Param) []Matcher {
	if len(argMatchers) == 0 {
		return transformParamsIntoEqMatchers(params)
	} else {
		checkArgument(len(argMatchers) == len(lastInvocation.Params),
			"You must use the same number of matchers as arguments. Example: TODO")
		return argMatchers
	}
}

func transformParamsIntoEqMatchers(params []Param) []Matcher {
	paramMatchers := make([]Matcher, len(params))
	for param := range params {
		paramMatchers = append(paramMatchers, &EqMatcher{param})
	}
	return paramMatchers
}

var genericMocks = make(map[Mock]*GenericMock)

func GetGenericMockFrom(mock Mock) *GenericMock {
	if genericMocks[mock] == nil {
		genericMocks[mock] = &GenericMock{mockedMethods: make(map[string]*mockedMethod)}
	}
	return genericMocks[mock]
}

func (stubbing *ongoingStubbing) ThenReturn(values ...ReturnValue) *ongoingStubbing {
	checkArguments(values, stubbing.returnValues)
	stubbing.genericMock.stub(stubbing.MethodName, stubbing.ParamMatchers, values)
	return stubbing
}

func checkArguments(stubbedReturnValues []ReturnValue, pseudoReturnValues []interface{}) {
	checkArgument(len(stubbedReturnValues) == len(pseudoReturnValues),
		"Different number of return values")
	for i := range stubbedReturnValues {
		checkArgument(reflect.TypeOf(stubbedReturnValues[i]) == reflect.TypeOf(pseudoReturnValues[i]),
			"Return type doesn't match")
	}
}

type Stubber struct {
	returnValue interface{}
}

func DoPanic(value interface{}) *Stubber {
	return &Stubber{returnValue: value}
}

func (stubber *Stubber) When(mock interface{}) {

}
<commit_msg>Minor refactorings<commit_after>// Copyright 2015 Peter Goetz
//
// 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 pegomock

import (
	"reflect"
	"testing"

	"github.com/petergtz/pegomock/pegomock/internal/testingtsupport"
	"github.com/petergtz/pegomock/pegomock/types"
)

var GlobalFailHandler types.FailHandler

func RegisterMockFailHandler(handler types.FailHandler) {
	GlobalFailHandler = handler
}
func RegisterMockTestingT(t *testing.T) {
	RegisterMockFailHandler(testingtsupport.BuildTestingTGomegaFailHandler(t))
}

type Mock interface{}
type Param interface{}
type ReturnValue interface{}
type ReturnValues []ReturnValue

var lastInvocation *invocation
var argMatchers Matchers

type invocation struct {
	genericMock *GenericMock
	MethodName  string
	Params      []Param
}

type GenericMock struct {
	mockedMethods map[string]*mockedMethod
}

func (genericMock *GenericMock) Invoke(methodName string, params ...Param) ReturnValues {
	lastInvocation = &invocation{
		genericMock: genericMock,
		MethodName:  methodName,
		Params:      params,
	}
	return genericMock.getOrCreateMockedMethod(methodName).Invoke(params)
}

func (genericMock *GenericMock) stub(methodName string, paramMatchers []Matcher, returnValues ReturnValues) {
	genericMock.getOrCreateMockedMethod(methodName).stub(paramMatchers, returnValues)
}

func (genericMock *GenericMock) getOrCreateMockedMethod(methodName string) *mockedMethod {
	if _, ok := genericMock.mockedMethods[methodName]; !ok {
		genericMock.mockedMethods[methodName] = &mockedMethod{name: methodName}
	}
	return genericMock.mockedMethods[methodName]
}

func (genericMock *GenericMock) Reset(methodName string, params []Matcher) {
	// TODO: should be called from When
}

func (genericMock *GenericMock) NumMethodInvocations(methodName string, params ...Param) int {
	if len(argMatchers) != 0 {
		checkArgument(len(argMatchers) == len(params),
			"If you use matchers, you must use matchers for all parameters. Example: TODO")
		result := genericMock.numMethodInvocationsUsingMatchers(methodName, argMatchers)
		argMatchers = nil
		return result
	}

	count := 0
	for _, invocation := range genericMock.mockedMethods[methodName].invocations {
		if reflect.DeepEqual(params, invocation) {
			count++
		}
	}
	return count
}

func (genericMock *GenericMock) numMethodInvocationsUsingMatchers(methodName string, paramMatchers Matchers) int {
	count := 0
	for _, invocation := range genericMock.mockedMethods[methodName].invocations {
		if paramMatchers.matches(invocation) {
			count++
		}
	}
	return count
}

type mockedMethod struct {
	name        string
	invocations [][]Param
	stubbings   Stubbings
}

func (method *mockedMethod) Invoke(params []Param) ReturnValues {
	method.invocations = append(method.invocations, params)
	stubbing := method.stubbings.find(params)
	if stubbing == nil {
		return ReturnValues{}
	}
	return stubbing.Invoke(params)
}

func (method *mockedMethod) stub(paramMatchers Matchers, returnValues ReturnValues) {
	stubbing := method.stubbings.findByMatchers(paramMatchers)
	if stubbing == nil {
		stubbing = &Stubbing{paramMatchers: paramMatchers}
		method.stubbings = append(method.stubbings, stubbing)
	}
	stubbing.returnValuesSequence = append(stubbing.returnValuesSequence, returnValues)
}

func (method *mockedMethod) removeLastInvocation() {
	method.invocations = method.invocations[:len(method.invocations)-1]
}

type Stubbings []*Stubbing

func (stubbings Stubbings) find(params []Param) *Stubbing {
	for _, stubbing := range stubbings {
		if stubbing.paramMatchers.matches(params) {
			return stubbing
		}
	}
	return nil
}

func (stubbings Stubbings) findByMatchers(paramMatchers Matchers) *Stubbing {
	for _, stubbing := range stubbings {
		if reflect.DeepEqual(stubbing.paramMatchers, paramMatchers) {
			return stubbing
		}
	}
	return nil
}

type Stubbing struct {
	paramMatchers        Matchers
	returnValuesSequence []ReturnValues
	sequencePointer      int
}

func (stubbing *Stubbing) Invoke(params []Param) ReturnValues {
	result := stubbing.returnValuesSequence[stubbing.sequencePointer]
	if stubbing.sequencePointer < len(stubbing.returnValuesSequence)-1 {
		stubbing.sequencePointer++
	}
	return result
}

type Matchers []Matcher

func (matchers Matchers) matches(params []Param) bool {
	checkArgument(len(matchers) == len(params),
		"Number of params and matchers different: params: %v, matchers: %v",
		params, matchers)
	for i := range params {
		if !matchers[i].matches(params[i]) {
			return false
		}
	}
	return true
}

func (matchers *Matchers) append(matcher Matcher) {
	*matchers = append(*matchers, matcher)
}

type ongoingStubbing struct {
	genericMock   *GenericMock
	MethodName    string
	ParamMatchers []Matcher
	returnValues  []interface{}
}

func When(invocation ...interface{}) *ongoingStubbing {
	checkNotNil(lastInvocation,
		"when() requires an argument which has to be 'a method call on a mock'.")
	defer func() {
		lastInvocation = nil
		argMatchers = nil
	}()
	lastInvocation.genericMock.mockedMethods[lastInvocation.MethodName].removeLastInvocation()
	return &ongoingStubbing{
		genericMock:   lastInvocation.genericMock,
		MethodName:    lastInvocation.MethodName,
		ParamMatchers: paramMatchersFromArgMatchersOrParams(argMatchers, lastInvocation.Params),
		returnValues:  invocation,
	}
}

func paramMatchersFromArgMatchersOrParams(argMatchers []Matcher, params []Param) []Matcher {
	if len(argMatchers) == 0 {
		return transformParamsIntoEqMatchers(params)
	} else {
		checkArgument(len(argMatchers) == len(lastInvocation.Params),
			"You must use the same number of matchers as arguments. Example: TODO")
		return argMatchers
	}
}

func transformParamsIntoEqMatchers(params []Param) []Matcher {
	paramMatchers := make([]Matcher, len(params))
	for param := range params {
		paramMatchers = append(paramMatchers, &EqMatcher{param})
	}
	return paramMatchers
}

var genericMocks = make(map[Mock]*GenericMock)

func GetGenericMockFrom(mock Mock) *GenericMock {
	if genericMocks[mock] == nil {
		genericMocks[mock] = &GenericMock{mockedMethods: make(map[string]*mockedMethod)}
	}
	return genericMocks[mock]
}

func (stubbing *ongoingStubbing) ThenReturn(values ...ReturnValue) *ongoingStubbing {
	checkArguments(values, stubbing.returnValues)
	stubbing.genericMock.stub(stubbing.MethodName, stubbing.ParamMatchers, values)
	return stubbing
}

func checkArguments(stubbedReturnValues []ReturnValue, pseudoReturnValues []interface{}) {
	checkArgument(len(stubbedReturnValues) == len(pseudoReturnValues),
		"Different number of return values")
	for i := range stubbedReturnValues {
		checkArgument(reflect.TypeOf(stubbedReturnValues[i]) == reflect.TypeOf(pseudoReturnValues[i]),
			"Return type doesn't match")
	}
}

type Stubber struct {
	returnValue interface{}
}

func DoPanic(value interface{}) *Stubber {
	return &Stubber{returnValue: value}
}

func (stubber *Stubber) When(mock interface{}) {

}
<|endoftext|>


<commit_before>// Package libsacloud is the SAKURA CLOUD API v1.1 Client for Go.
package libsacloud

// Version バージョン
const Version = "1.24.1"
<commit_msg>Bump to v1.25.0<commit_after>// Package libsacloud is the SAKURA CLOUD API v1.1 Client for Go.
package libsacloud

// Version バージョン
const Version = "1.25.0"
<|endoftext|>


<commit_before>package main

import(
	"os"
	"flag"
	"log"
	"image"
	"image/jpeg"
	//_"image/png"
	//_"image/gif"
	"image/color"
	)

//Estrucuta de imagen
type img struct{
	h,w int
	c [][]color.RGBA
}

//Metodos que se necesitan para manejar imagen
func (m img) At(x, y int) color.Color { return m.c[x][y] }
func (m img) ColorModel() color.Model { return color.RGBAModel }
func (m img) Bounds() image.Rectangle { return image.Rect(0, 0, m.h, m.w) }

/*
El maximo cogera un array de valores y de ellos devolvera el maximo
no como la mierda de Max(a float64,b float64)
*/
func  Max(a []uint8) uint8{
	var max uint8=a[0]
	for i:=0;i<len(a)-1;i++{
		if max < a[i+1] {max=a[i]}
	}
	return max
}

/*
Again
*/
func Min(a []uint8) uint8{
	var min uint8=a[0]
	for i:=0;i<len(a)-1;i++{
		if min > a[i+1] {min=a[i]}
	}
	return min
}

/*
Un par de flags que permitan al programador elegir imagen de entrada y nombre
de nueva imagen de saldia.
*/
var(

	img1=flag.String("img1","../../joker.jpg","nombre de la foto")
	img2=flag.String("img2","../../imagen3.jpg","nombre del archivo de salida")
)

/*
Este metodo se encarga de crear una nueva imagen de tipo img y haremos los
filtros necesarios para el resultado(en este caso paso a escala de grises)
*/
func Create(imagen image.Image) img{

	/*
	Los datos de la nueva imagen los seleccionamos en funcion de la
	de entrada.
	*/
	a:=imagen.Bounds().Max.X - imagen.Bounds().Min.X
	b:=imagen.Bounds().Max.Y - imagen.Bounds().Min.Y
	c := make([][]color.RGBA,a)

	for i := range c {
		c[i] = make([]color.RGBA,b)
	}

	/*
	Creamos la nueva imagen
	*/
	m:= img{a,b,c}

	//cosas del preprocesador
	var mm int= m.h
	//pragma gomp parallel for
	for i:=0;i<mm;i++{
		for j:=0;j<m.w;j++{
			/*
			Sacamos los colores de la imagen de entrada
			*/
			_r,_g,_b,_a:=imagen.At(i,j).RGBA()

			/*
			cd es el valor devuelto por el algoritmo que elijamos para
			modificar el color de la imagen
			*/
			//cd:=(Max([]uint8{uint8(_r),uint8(_g),uint8(_b)})+Min([]uint8{uint8(_b),uint8(_g),uint8(_b)}))/2
			//cd:=(uint8(_a)+uint8(_b)+uint8(_c))/3
			cd:=float64(uint8(_r))*0.30+float64(uint8(_g))*0.59+float64(uint8(_b))*0.11
			/*
			Seleccionamos color de cada pixel de la nueva imagen, valores uint8
			aunque los devueltos por la imagen original son de 32
			*/
			m.c[i][j].R, m.c[i][j].G, m.c[i][j].B, m.c[i][j].A=uint8(cd),uint8(cd),uint8(cd),uint8(_a)

		}
	}

	return m
}

func main(){
	//parsea los flags de entrada
	flag.Parse()

	//Crea el archivo de salida
	f,_:=os.Create(*img2)

	//abre el fichero a copiar
	f1,err:=os.Open(*img1)
	if err != nil {
	log.Fatal(err)
}
	//decodifica la imagen a copiar para obtener sus datos (tamaño y color)
	img,_,err:=image.Decode(f1)
	if err!=nil{
		log.Fatal(err)
	}

	/*
	Llamada a la funcion que cumplira la funcion de modificar la imagen pixel
	a pixel e ir guardando dichos pixel en la matriz de colores de la nueva
	imagen.
	*/
	img1:=Create(img)
	err = jpeg.Encode(f,img1,nil)
	err = jpeg.Encode(f, img,&jpeg.Options{100})
}<commit_msg>version 0.1<commit_after>package main

import(
	"os"
	"flag"
	"log"
	"image"
	"image/jpeg"
	_"image/png"
	_"image/gif"
	"image/color"
	)

//Estrucuta de imagen
type img struct{
	h,w int
	c [][]color.RGBA
}

//Metodos que se necesitan para manejar imagen
func (m img) At(x, y int) color.Color { return m.c[x][y] }
func (m img) ColorModel() color.Model { return color.RGBAModel }
func (m img) Bounds() image.Rectangle { return image.Rect(0, 0, m.h, m.w) }

/*
El maximo cogera un array de valores y de ellos devolvera el maximo
no como la mierda de Max(a float64,b float64)
*/
func  Max(a []uint8) uint8{
	var max uint8=a[0]
	for i:=0;i<len(a)-1;i++{
		if max < a[i+1] {max=a[i]}
	}
	return max
}

/*
Again
*/
func Min(a []uint8) uint8{
	var min uint8=a[0]
	for i:=0;i<len(a)-1;i++{
		if min > a[i+1] {min=a[i]}
	}
	return min
}

/*
Un par de flags que permitan al programador elegir imagen de entrada y nombre
de nueva imagen de saldia.
*/
var(

	img1=flag.String("img1","../../joker.jpg","nombre de la foto")
	img2=flag.String("img2","../../imagen3.jpg","nombre del archivo de salida")
)

/*
Este metodo se encarga de crear una nueva imagen de tipo img y haremos los
filtros necesarios para el resultado(en este caso paso a escala de grises)
*/
func Create(imagen image.Image) img{

	/*
	Los datos de la nueva imagen los seleccionamos en funcion de la
	de entrada.
	*/
	a:=imagen.Bounds().Max.X - imagen.Bounds().Min.X
	b:=imagen.Bounds().Max.Y - imagen.Bounds().Min.Y
	c := make([][]color.RGBA,a)

	for i := range c {
		c[i] = make([]color.RGBA,b)
	}

	/*
	Creamos la nueva imagen
	*/
	m:= img{a,b,c}

	//cosas del preprocesador
	var mm int= m.h
	//pragma gomp parallel for
	for i:=0;i<mm;i++{
		for j:=0;j<m.w;j++{
			/*
			Sacamos los colores de la imagen de entrada
			*/
			_r,_g,_b,_a:=imagen.At(i,j).RGBA()

			/*
			cd es el valor devuelto por el algoritmo que elijamos para
			modificar el color de la imagen
			*/
			//cd:=(Max([]uint8{uint8(_r),uint8(_g),uint8(_b)})+Min([]uint8{uint8(_b),uint8(_g),uint8(_b)}))/2
			//cd:=(uint8(_a)+uint8(_b)+uint8(_c))/3
			cd:=float64(uint8(_r))*0.30+float64(uint8(_g))*0.59+float64(uint8(_b))*0.11
			/*
			Seleccionamos color de cada pixel de la nueva imagen, valores uint8
			aunque los devueltos por la imagen original son de 32
			*/
			m.c[i][j].R, m.c[i][j].G, m.c[i][j].B, m.c[i][j].A=uint8(cd),uint8(cd),uint8(cd),uint8(_a)

		}
	}

	return m
}

func main(){
	//parsea los flags de entrada
	flag.Parse()

	//Crea el archivo de salida
	f,_:=os.Create(*img2)

	//abre el fichero a copiar
	f1,err:=os.Open(*img1)
	if err != nil {
	log.Fatal(err)
}
	//decodifica la imagen a copiar para obtener sus datos (tamaño y color)
	img,_,err:=image.Decode(f1)
	if err!=nil{
		log.Fatal(err)
	}

	/*
	Llamada a la funcion que cumplira la funcion de modificar la imagen pixel
	a pixel e ir guardando dichos pixel en la matriz de colores de la nueva
	imagen.
	*/
	img1:=Create(img)
	err = jpeg.Encode(f,img1,nil)
	err = jpeg.Encode(f, img,&jpeg.Options{100})
}<|endoftext|>


<commit_before>package quic

import (
	"crypto/tls"
	"io"
	"net"
	"time"

	"github.com/lucas-clemente/quic-go/protocol"
)

// Stream is the interface implemented by QUIC streams
type Stream interface {
	io.Reader
	io.Writer
	io.Closer
	StreamID() protocol.StreamID
	// Reset closes the stream with an error.
	Reset(error)
}

// A Session is a QUIC connection between two peers.
type Session interface {
	// AcceptStream returns the next stream opened by the peer, blocking until one is available.
	// Since stream 1 is reserved for the crypto stream, the first stream is either 2 (for a client) or 3 (for a server).
	AcceptStream() (Stream, error)
	// OpenStream opens a new QUIC stream, returning a special error when the peeer's concurrent stream limit is reached.
	// New streams always have the smallest possible stream ID.
	// TODO: Enable testing for the special error
	OpenStream() (Stream, error)
	// OpenStreamSync opens a new QUIC stream, blocking until the peer's concurrent stream limit allows a new stream to be opened.
	// It always picks the smallest possible stream ID.
	OpenStreamSync() (Stream, error)
	// LocalAddr returns the local address.
	LocalAddr() net.Addr
	// RemoteAddr returns the address of the peer.
	RemoteAddr() net.Addr
	// Close closes the connection. The error will be sent to the remote peer in a CONNECTION_CLOSE frame. An error value of nil is allowed and will cause a normal PeerGoingAway to be sent.
	Close(error) error
}

// A NonFWSession is a QUIC connection between two peers half-way through the handshake.
// The communication is encrypted, but not yet forward secure.
type NonFWSession interface {
	Session
	WaitUntilHandshakeComplete() error
}

// An STK is a Source Address token.
// It is issued by the server and sent to the client. For the client, it is an opaque blob.
// The client can send the STK in subsequent handshakes to prove ownership of its IP address.
type STK struct {
	// The remote address this token was issued for.
	// If the server is run on a net.UDPConn, this is the string representation of the IP address (net.IP.String())
	// Otherwise, this is the string representation of the net.Addr (net.Addr.String())
	remoteAddr string
	// The time that the STK was issued (resolution 1 second)
	sentTime time.Time
}

// Config contains all configuration data needed for a QUIC server or client.
// More config parameters (such as timeouts) will be added soon, see e.g. https://github.com/lucas-clemente/quic-go/issues/441.
type Config struct {
	TLSConfig *tls.Config
	// The QUIC versions that can be negotiated.
	// If not set, it uses all versions available.
	// Warning: This API should not be considered stable and will change soon.
	Versions []protocol.VersionNumber
	// Ask the server to truncate the connection ID sent in the Public Header.
	// If not set, the default checks if
	// This saves 8 bytes in the Public Header in every packet. However, if the IP address of the server changes, the connection cannot be migrated.
	// Currently only valid for the client.
	RequestConnectionIDTruncation bool
	// HandshakeTimeout is the maximum duration that the cryptographic handshake may take.
	// If the timeout is exceeded, the connection is closed.
	// If this value is zero, the timeout is set to 10 seconds.
	HandshakeTimeout time.Duration
	// AcceptSTK determines if an STK is accepted.
	// It is called with stk = nil if the client didn't send an STK.
	// If not set, it verifies that the address matches, and that the STK was issued within the last 24 hours
	// This option is only valid for the server.
	AcceptSTK func(clientAddr net.Addr, stk *STK) bool
}

// A Listener for incoming QUIC connections
type Listener interface {
	// Close the server, sending CONNECTION_CLOSE frames to each peer.
	Close() error
	// Addr returns the local network addr that the server is listening on.
	Addr() net.Addr
	// Accept returns new sessions. It should be called in a loop.
	Accept() (Session, error)
}
<commit_msg>Remove incomplete and unnecessary sentence in docs<commit_after>package quic

import (
	"crypto/tls"
	"io"
	"net"
	"time"

	"github.com/lucas-clemente/quic-go/protocol"
)

// Stream is the interface implemented by QUIC streams
type Stream interface {
	io.Reader
	io.Writer
	io.Closer
	StreamID() protocol.StreamID
	// Reset closes the stream with an error.
	Reset(error)
}

// A Session is a QUIC connection between two peers.
type Session interface {
	// AcceptStream returns the next stream opened by the peer, blocking until one is available.
	// Since stream 1 is reserved for the crypto stream, the first stream is either 2 (for a client) or 3 (for a server).
	AcceptStream() (Stream, error)
	// OpenStream opens a new QUIC stream, returning a special error when the peeer's concurrent stream limit is reached.
	// New streams always have the smallest possible stream ID.
	// TODO: Enable testing for the special error
	OpenStream() (Stream, error)
	// OpenStreamSync opens a new QUIC stream, blocking until the peer's concurrent stream limit allows a new stream to be opened.
	// It always picks the smallest possible stream ID.
	OpenStreamSync() (Stream, error)
	// LocalAddr returns the local address.
	LocalAddr() net.Addr
	// RemoteAddr returns the address of the peer.
	RemoteAddr() net.Addr
	// Close closes the connection. The error will be sent to the remote peer in a CONNECTION_CLOSE frame. An error value of nil is allowed and will cause a normal PeerGoingAway to be sent.
	Close(error) error
}

// A NonFWSession is a QUIC connection between two peers half-way through the handshake.
// The communication is encrypted, but not yet forward secure.
type NonFWSession interface {
	Session
	WaitUntilHandshakeComplete() error
}

// An STK is a Source Address token.
// It is issued by the server and sent to the client. For the client, it is an opaque blob.
// The client can send the STK in subsequent handshakes to prove ownership of its IP address.
type STK struct {
	// The remote address this token was issued for.
	// If the server is run on a net.UDPConn, this is the string representation of the IP address (net.IP.String())
	// Otherwise, this is the string representation of the net.Addr (net.Addr.String())
	remoteAddr string
	// The time that the STK was issued (resolution 1 second)
	sentTime time.Time
}

// Config contains all configuration data needed for a QUIC server or client.
// More config parameters (such as timeouts) will be added soon, see e.g. https://github.com/lucas-clemente/quic-go/issues/441.
type Config struct {
	TLSConfig *tls.Config
	// The QUIC versions that can be negotiated.
	// If not set, it uses all versions available.
	// Warning: This API should not be considered stable and will change soon.
	Versions []protocol.VersionNumber
	// Ask the server to truncate the connection ID sent in the Public Header.
	// This saves 8 bytes in the Public Header in every packet. However, if the IP address of the server changes, the connection cannot be migrated.
	// Currently only valid for the client.
	RequestConnectionIDTruncation bool
	// HandshakeTimeout is the maximum duration that the cryptographic handshake may take.
	// If the timeout is exceeded, the connection is closed.
	// If this value is zero, the timeout is set to 10 seconds.
	HandshakeTimeout time.Duration
	// AcceptSTK determines if an STK is accepted.
	// It is called with stk = nil if the client didn't send an STK.
	// If not set, it verifies that the address matches, and that the STK was issued within the last 24 hours
	// This option is only valid for the server.
	AcceptSTK func(clientAddr net.Addr, stk *STK) bool
}

// A Listener for incoming QUIC connections
type Listener interface {
	// Close the server, sending CONNECTION_CLOSE frames to each peer.
	Close() error
	// Addr returns the local network addr that the server is listening on.
	Addr() net.Addr
	// Accept returns new sessions. It should be called in a loop.
	Accept() (Session, error)
}
<|endoftext|>


<commit_before>// Copyright 2015 The TCell Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use 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 tcell

import (
	"time"
)

// EventInterrupt is a generic wakeup event.  Its can be used to
// to request a redraw.  It can carry an arbitrary payload, as well.
type EventInterrupt struct {
	t time.Time
	v interface{}
        esc string
}

// When returns the time when this event was created.
func (ev *EventInterrupt) When() time.Time {
	return ev.t
}

func (ev *EventInterrupt) EscSeq() string {
	return ev.esc
}

// Data is used to obtain the opaque event payload.
func (ev *EventInterrupt) Data() interface{} {
	return ev.v
}

// NewEventInterrupt creates an EventInterrupt with the given payload.
func NewEventInterrupt(data interface{}) *EventInterrupt {
	return &EventInterrupt{t: time.Now(), v: data}
}
<commit_msg>Format<commit_after>// Copyright 2015 The TCell Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use 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 tcell

import (
	"time"
)

// EventInterrupt is a generic wakeup event.  Its can be used to
// to request a redraw.  It can carry an arbitrary payload, as well.
type EventInterrupt struct {
	t   time.Time
	v   interface{}
	esc string
}

// When returns the time when this event was created.
func (ev *EventInterrupt) When() time.Time {
	return ev.t
}

func (ev *EventInterrupt) EscSeq() string {
	return ev.esc
}

// Data is used to obtain the opaque event payload.
func (ev *EventInterrupt) Data() interface{} {
	return ev.v
}

// NewEventInterrupt creates an EventInterrupt with the given payload.
func NewEventInterrupt(data interface{}) *EventInterrupt {
	return &EventInterrupt{t: time.Now(), v: data}
}
<|endoftext|>


<commit_before>// Copyright 2016 The Gosl Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package io

import (
	"bufio"
	"bytes"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"

	"github.com/cpmech/gosl/chk"
)

// functions to handle filenames //////////////////////////////////////////////////////////////////

// FnKey returns the file name key (without path and extension, if any)
func FnKey(fn string) string {
	base := filepath.Base(fn)
	return base[:len(base)-len(filepath.Ext(base))]
}

// FnExt returns the extension of a file name.
// The extension is the suffix beginning at the final dot in the final element of path; it is empty if there is no dot.
func FnExt(fn string) string {
	return filepath.Ext(fn)
}

// PathKey returs the full path except the extension
func PathKey(fn string) string {
	return fn[:len(fn)-len(filepath.Ext(fn))]
}

// RemoveAll deletes all files matching filename specified by key (be careful)
func RemoveAll(key string) {
	fns, _ := filepath.Glob(os.ExpandEnv(key))
	for _, fn := range fns {
		os.RemoveAll(fn)
	}
}

// functions to write files ///////////////////////////////////////////////////////////////////////

// AppendToFile appends data to an existent (or new) file
func AppendToFile(fn string, buffer ...*bytes.Buffer) {
	fil, err := os.OpenFile(os.ExpandEnv(fn), os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
	if err != nil {
		chk.Panic("cannot create file <%s>", fn)
	}
	defer fil.Close()
	for k := range buffer {
		if buffer[k] != nil {
			fil.Write(buffer[k].Bytes())
		}
	}
}

// WriteFile writes data to a new file with given bytes.Buffer(s)
func WriteFile(fn string, buffer ...*bytes.Buffer) {
	fil, err := os.Create(os.ExpandEnv(fn))
	if err != nil {
		chk.Panic("cannot create file <%s>", fn)
	}
	defer fil.Close()
	for k := range buffer {
		if buffer[k] != nil {
			fil.Write(buffer[k].Bytes())
		}
	}
}

// WriteFileD writes data to a new file after creating a directory
func WriteFileD(dirout, fn string, buffer ...*bytes.Buffer) {
	os.MkdirAll(dirout, 0777)
	WriteFile(filepath.Join(dirout, fn), buffer...)
}

// WriteFileV writes data to a new file, and shows message
func WriteFileV(fn string, buffer ...*bytes.Buffer) {
	WriteFile(fn, buffer...)
	Pf("file <%s> written\n", fn)
}

// WriteFileVD writes data to a new file, and shows message after creating a directory
func WriteFileVD(dirout, fn string, buffer ...*bytes.Buffer) {
	WriteFileD(dirout, fn, buffer...)
	Pf("file <%s> written\n", filepath.Join(dirout, fn))
}

// WriteStringToFile writes string to a new file
func WriteStringToFile(fn, data string) {
	fil, err := os.Create(os.ExpandEnv(fn))
	if err != nil {
		chk.Panic("cannot create file <%s>", fn)
	}
	defer fil.Close()
	fil.WriteString(data)
}

// WriteStringToFileD writes string to a new file after creating a directory
func WriteStringToFileD(dirout, fn, data string) {
	os.MkdirAll(dirout, 0777)
	WriteStringToFile(filepath.Join(dirout, fn), data)
}

// WriteBytesToFile writes slice of bytes to a new file
func WriteBytesToFile(fn string, b []byte) {
	fil, err := os.Create(os.ExpandEnv(fn))
	if err != nil {
		chk.Panic("cannot create file <%s>", fn)
	}
	defer fil.Close()
	if _, err = fil.Write(b); err != nil {
		chk.Panic("%v", err)
	}
}

// WriteBytesToFileD writes slice of bytes to a new file after creating a directory
func WriteBytesToFileD(dirout, fn string, b []byte) {
	os.MkdirAll(dirout, 0777)
	WriteBytesToFile(filepath.Join(dirout, fn), b)
}

// WriteBytesToFileVD writes slice of bytes to a new file, and print message, after creating a directory
func WriteBytesToFileVD(dirout, fn string, b []byte) {
	os.MkdirAll(dirout, 0777)
	WriteBytesToFile(filepath.Join(dirout, fn), b)
	Pf("file <%s> written\n", filepath.Join(dirout, fn))
}

// functions to read files ////////////////////////////////////////////////////////////////////////

// OpenFileR opens a file for reading data
func OpenFileR(fn string) (fil *os.File) {
	fil, err := os.Open(os.ExpandEnv(fn))
	if err != nil {
		chk.Panic("%v\n", err)
	}
	return
}

// ReadFile reads bytes from a file
func ReadFile(fn string) (b []byte) {
	b, err := ioutil.ReadFile(os.ExpandEnv(fn))
	if err != nil {
		chk.Panic("%v\n", err)
	}
	return
}

// ReadLinesCallback is used in ReadLines to process line by line during reading of a file
type ReadLinesCallback func(idx int, line string) (stop bool)

// ReadLines reads lines from a file and calls ReadLinesCallback to process each line being read
func ReadLines(fn string, cb ReadLinesCallback) {
	fil, err := os.Open(os.ExpandEnv(fn))
	if err != nil {
		chk.Panic("%v\n", err)
	}
	defer fil.Close()
	r := bufio.NewReader(fil)
	idx := 0
	for {
		lin, prefix, errl := r.ReadLine()
		if prefix {
			err = chk.Err("cannot read long line. file = <%s>", fn)
			return
		}
		if errl == io.EOF {
			break
		}
		if errl != nil {
			err = chk.Err("cannot read line. file = <%s>", fn)
			return
		}
		stop := cb(idx, string(lin))
		if stop {
			break
		}
		idx++
	}
}

// ReadLinesFile reads lines from a file and calls ReadLinesCallback to process each line being read
func ReadLinesFile(fil *os.File, cb ReadLinesCallback) {
	r := bufio.NewReader(fil)
	idx := 0
	for {
		lin, prefix, errl := r.ReadLine()
		if prefix {
			chk.Panic("cannot read long line. file = <%s>\n", fil.Name())
		}
		if errl == io.EOF {
			break
		}
		if errl != nil {
			chk.Panic("cannot read line. file = <%s>\n", fil.Name())
		}
		stop := cb(idx, string(lin))
		if stop {
			break
		}
		idx++
	}
}

// ReadTable reads a text file in which the first line contains the headers and the next lines the float64
// type of numeric values. The number of columns must be equal, including for the headers
func ReadTable(fn string) (keys []string, T map[string][]float64) {
	f := OpenFileR(fn)
	header := true
	ReadLinesFile(f, func(idx int, line string) (stop bool) {
		r := strings.Fields(line)
		if len(r) == 0 { // skip empty lines
			return
		}
		if r[0] == "#" { // skip comments
			return
		}
		ncol := len(r)
		if ncol < 1 {
			chk.Panic("number of columns must be at least 1\n")
		}
		if header {
			T = make(map[string][]float64)
			keys = make([]string, ncol)
			for i := 0; i < ncol; i++ {
				keys[i] = r[i]
				T[r[i]] = make([]float64, 0)
			}
			header = false
		} else {
			for i := 0; i < ncol; i++ {
				T[keys[i]] = append(T[keys[i]], Atof(r[i]))
			}
		}
		return
	})
	return
}

// ReadMatrix reads a text file in which the float64 type of numeric values represent
// a matrix of data. The number of columns must be equal, including for the headers
func ReadMatrix(fn string) (M [][]float64) {
	f := OpenFileR(fn)
	ncolFix := 0
	ReadLinesFile(f, func(idx int, line string) (stop bool) {
		r := strings.Fields(line)
		if len(r) == 0 { // skip empty lines
			return
		}
		if r[0] == "#" { // skip comments
			return
		}
		ncol := len(r)
		if ncol < 1 {
			chk.Panic("number of columns must be at least 1\n")
		}
		if M == nil {
			M = make([][]float64, 0)
			ncolFix = ncol
		}
		if ncol != ncolFix {
			chk.Panic("number of columns must be equal for all lines. %d != %d\n", ncol, ncolFix)
		}
		vals := make([]float64, ncol)
		for i := 0; i < ncol; i++ {
			vals[i] = Atof(r[i])
		}
		M = append(M, vals)
		return
	})
	return
}
<commit_msg>Fix unused chk.Err call<commit_after>// Copyright 2016 The Gosl Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package io

import (
	"bufio"
	"bytes"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"

	"github.com/cpmech/gosl/chk"
)

// functions to handle filenames //////////////////////////////////////////////////////////////////

// FnKey returns the file name key (without path and extension, if any)
func FnKey(fn string) string {
	base := filepath.Base(fn)
	return base[:len(base)-len(filepath.Ext(base))]
}

// FnExt returns the extension of a file name.
// The extension is the suffix beginning at the final dot in the final element of path; it is empty if there is no dot.
func FnExt(fn string) string {
	return filepath.Ext(fn)
}

// PathKey returs the full path except the extension
func PathKey(fn string) string {
	return fn[:len(fn)-len(filepath.Ext(fn))]
}

// RemoveAll deletes all files matching filename specified by key (be careful)
func RemoveAll(key string) {
	fns, _ := filepath.Glob(os.ExpandEnv(key))
	for _, fn := range fns {
		os.RemoveAll(fn)
	}
}

// functions to write files ///////////////////////////////////////////////////////////////////////

// AppendToFile appends data to an existent (or new) file
func AppendToFile(fn string, buffer ...*bytes.Buffer) {
	fil, err := os.OpenFile(os.ExpandEnv(fn), os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
	if err != nil {
		chk.Panic("cannot create file <%s>", fn)
	}
	defer fil.Close()
	for k := range buffer {
		if buffer[k] != nil {
			fil.Write(buffer[k].Bytes())
		}
	}
}

// WriteFile writes data to a new file with given bytes.Buffer(s)
func WriteFile(fn string, buffer ...*bytes.Buffer) {
	fil, err := os.Create(os.ExpandEnv(fn))
	if err != nil {
		chk.Panic("cannot create file <%s>", fn)
	}
	defer fil.Close()
	for k := range buffer {
		if buffer[k] != nil {
			fil.Write(buffer[k].Bytes())
		}
	}
}

// WriteFileD writes data to a new file after creating a directory
func WriteFileD(dirout, fn string, buffer ...*bytes.Buffer) {
	os.MkdirAll(dirout, 0777)
	WriteFile(filepath.Join(dirout, fn), buffer...)
}

// WriteFileV writes data to a new file, and shows message
func WriteFileV(fn string, buffer ...*bytes.Buffer) {
	WriteFile(fn, buffer...)
	Pf("file <%s> written\n", fn)
}

// WriteFileVD writes data to a new file, and shows message after creating a directory
func WriteFileVD(dirout, fn string, buffer ...*bytes.Buffer) {
	WriteFileD(dirout, fn, buffer...)
	Pf("file <%s> written\n", filepath.Join(dirout, fn))
}

// WriteStringToFile writes string to a new file
func WriteStringToFile(fn, data string) {
	fil, err := os.Create(os.ExpandEnv(fn))
	if err != nil {
		chk.Panic("cannot create file <%s>", fn)
	}
	defer fil.Close()
	fil.WriteString(data)
}

// WriteStringToFileD writes string to a new file after creating a directory
func WriteStringToFileD(dirout, fn, data string) {
	os.MkdirAll(dirout, 0777)
	WriteStringToFile(filepath.Join(dirout, fn), data)
}

// WriteBytesToFile writes slice of bytes to a new file
func WriteBytesToFile(fn string, b []byte) {
	fil, err := os.Create(os.ExpandEnv(fn))
	if err != nil {
		chk.Panic("cannot create file <%s>", fn)
	}
	defer fil.Close()
	if _, err = fil.Write(b); err != nil {
		chk.Panic("%v", err)
	}
}

// WriteBytesToFileD writes slice of bytes to a new file after creating a directory
func WriteBytesToFileD(dirout, fn string, b []byte) {
	os.MkdirAll(dirout, 0777)
	WriteBytesToFile(filepath.Join(dirout, fn), b)
}

// WriteBytesToFileVD writes slice of bytes to a new file, and print message, after creating a directory
func WriteBytesToFileVD(dirout, fn string, b []byte) {
	os.MkdirAll(dirout, 0777)
	WriteBytesToFile(filepath.Join(dirout, fn), b)
	Pf("file <%s> written\n", filepath.Join(dirout, fn))
}

// functions to read files ////////////////////////////////////////////////////////////////////////

// OpenFileR opens a file for reading data
func OpenFileR(fn string) (fil *os.File) {
	fil, err := os.Open(os.ExpandEnv(fn))
	if err != nil {
		chk.Panic("%v\n", err)
	}
	return
}

// ReadFile reads bytes from a file
func ReadFile(fn string) (b []byte) {
	b, err := ioutil.ReadFile(os.ExpandEnv(fn))
	if err != nil {
		chk.Panic("%v\n", err)
	}
	return
}

// ReadLinesCallback is used in ReadLines to process line by line during reading of a file
type ReadLinesCallback func(idx int, line string) (stop bool)

// ReadLines reads lines from a file and calls ReadLinesCallback to process each line being read
func ReadLines(fn string, cb ReadLinesCallback) {
	fil, err := os.Open(os.ExpandEnv(fn))
	if err != nil {
		chk.Panic("%v\n", err)
	}
	defer fil.Close()
	r := bufio.NewReader(fil)
	idx := 0
	for {
		lin, prefix, errl := r.ReadLine()
		if prefix {
			chk.Panic("cannot read long line. file = <%s>", fn)
		}
		if errl == io.EOF {
			break
		}
		if errl != nil {
			chk.Panic("cannot read line. file = <%s>", fn)
		}
		stop := cb(idx, string(lin))
		if stop {
			break
		}
		idx++
	}
}

// ReadLinesFile reads lines from a file and calls ReadLinesCallback to process each line being read
func ReadLinesFile(fil *os.File, cb ReadLinesCallback) {
	r := bufio.NewReader(fil)
	idx := 0
	for {
		lin, prefix, errl := r.ReadLine()
		if prefix {
			chk.Panic("cannot read long line. file = <%s>\n", fil.Name())
		}
		if errl == io.EOF {
			break
		}
		if errl != nil {
			chk.Panic("cannot read line. file = <%s>\n", fil.Name())
		}
		stop := cb(idx, string(lin))
		if stop {
			break
		}
		idx++
	}
}

// ReadTable reads a text file in which the first line contains the headers and the next lines the float64
// type of numeric values. The number of columns must be equal, including for the headers
func ReadTable(fn string) (keys []string, T map[string][]float64) {
	f := OpenFileR(fn)
	header := true
	ReadLinesFile(f, func(idx int, line string) (stop bool) {
		r := strings.Fields(line)
		if len(r) == 0 { // skip empty lines
			return
		}
		if r[0] == "#" { // skip comments
			return
		}
		ncol := len(r)
		if ncol < 1 {
			chk.Panic("number of columns must be at least 1\n")
		}
		if header {
			T = make(map[string][]float64)
			keys = make([]string, ncol)
			for i := 0; i < ncol; i++ {
				keys[i] = r[i]
				T[r[i]] = make([]float64, 0)
			}
			header = false
		} else {
			for i := 0; i < ncol; i++ {
				T[keys[i]] = append(T[keys[i]], Atof(r[i]))
			}
		}
		return
	})
	return
}

// ReadMatrix reads a text file in which the float64 type of numeric values represent
// a matrix of data. The number of columns must be equal, including for the headers
func ReadMatrix(fn string) (M [][]float64) {
	f := OpenFileR(fn)
	ncolFix := 0
	ReadLinesFile(f, func(idx int, line string) (stop bool) {
		r := strings.Fields(line)
		if len(r) == 0 { // skip empty lines
			return
		}
		if r[0] == "#" { // skip comments
			return
		}
		ncol := len(r)
		if ncol < 1 {
			chk.Panic("number of columns must be at least 1\n")
		}
		if M == nil {
			M = make([][]float64, 0)
			ncolFix = ncol
		}
		if ncol != ncolFix {
			chk.Panic("number of columns must be equal for all lines. %d != %d\n", ncol, ncolFix)
		}
		vals := make([]float64, ncol)
		for i := 0; i < ncol; i++ {
			vals[i] = Atof(r[i])
		}
		M = append(M, vals)
		return
	})
	return
}
<|endoftext|>


<commit_before>package goDLX

import (
	"strings"
	"testing"
)

// TestNew tests that creating a new Head actually does create a new Head.
// Nothing to verify other than a lack of errors.
func TestNew(t *testing.T) {
	h := New()
	if h == nil {
		t.Errorf("New(): Did not return a valid Head node")
	}
	if !assertCircleLft(h, 1) {
		t.Errorf("New(): Head not circular to the left")
	}
	if !assertCircleRgt(h, 1) {
		t.Errorf("New(): Head not circular to the right")
	}
}

func TestHeadLft(t *testing.T) {
	h := New()
	if lft := h.lft(); lft == nil {
		t.Errorf("Head.lft(): No node returned on left")
	}
}

func TestHeadSetLft(t *testing.T) {
	h := New()
	oh := new(Head)
	c := new(column)
	e := new(element)
	allowed := []node{h, c}
	forbidden := []node{oh, nil, e}
	for _, i := range allowed {
		if n, err := h.setLft(i); err != nil || n != i {
			t.Error(i)
		} else if !assertLft(h, i) {
			t.Error(i)
		}
	}
	for _, i := range forbidden {
		if n, err := h.setLft(i); err == nil || n != nil {
			t.Error(i)
		}
	}
}

func TestHeadRgt(t *testing.T) {
	h := New()
	if rgt := h.rgt(); rgt == nil {
		t.Errorf("Head.rgt(): No node returned on right")
	}
}

func TestHeadSetRgt(t *testing.T) {
	h := New()
	oh := new(Head)
	c := new(column)
	e := new(element)
	allowed := []node{h, c}
	forbidden := []node{oh, nil, e}
	for _, i := range allowed {
		if n, err := h.setRgt(i); err != nil || n != i {
			t.Error(i)
		} else if !assertRgt(h, i) {
			t.Error(i)
		}
	}
	for _, i := range forbidden {
		if n, err := h.setRgt(i); err == nil || n != nil {
			t.Error(i)
		}
	}
}

func TestHeadUp(t *testing.T) {
	h := New()
	if n := h.up(); n != h {
		t.Errorf("Head.up(): did not return self")
	}
}

func TestHeadSetUp(t *testing.T) {
	h := New()
	oh := new(Head)
	c := new(column)
	e := new(element)
	allowed := []node{}
	forbidden := []node{h, c, oh, e, nil}
	for _, i := range allowed {
		if n, err := h.setUp(i); err != nil || n != i {
			t.Error(i)
		} else if !assertUp(h, i) {
			t.Error(i)
		}
	}
	for _, i := range forbidden {
		if n, err := h.setUp(i); err == nil || n != nil {
			t.Error(i)
		}
	}
}

func TestHeadDn(t *testing.T) {
	h := New()
	if n := h.dn(); n != h {
		t.Errorf("Head.dn(): did not return self")
	}
}

func TestHeadSetDn(t *testing.T) {
	h := New()
	oh := new(Head)
	c := new(column)
	e := new(element)
	allowed := []node{}
	forbidden := []node{h, c, oh, e, nil}
	for _, i := range allowed {
		if n, err := h.setDn(i); err != nil || n != i {
			t.Error(i)
		} else if !assertDn(h, i) {
			t.Error(i)
		}
	}
	for _, i := range forbidden {
		if n, err := h.setDn(i); err == nil || n != nil {
			t.Error(i)
		}
	}
}

func TestHeadCol(t *testing.T) {
	h := New()
	if n := h.col(); n != h {
		t.Errorf("Head.col(): did not return self")
	}
}

func TestHeadAddCol(t *testing.T) {
	const colCount = 100
	h := New()
	for i := 0; i < colCount; i++ {
		h.AddCol(string(i), false)
		if !assertCircleLft(h, i+2) || !assertCircleRgt(h, i+2) {
			t.Errorf("Head.AddCol(name, optional): List no longer circular")
		}
	}
}

const testMatrix = `A,B,C,D,E,F,G
0010110
1001001
0110010
1001000
0100001
0001101
`
const solvedMatrix = `A,B,C,D,E,F,G
1001000
0100001
0010110
`

func TestHeadAddRow(t *testing.T) {
	h := New()
	// add the columns
	colCounts := make(map[string]int)
	colCounts["A"] = 2
	colCounts["B"] = 2
	colCounts["C"] = 2
	colCounts["D"] = 3
	colCounts["E"] = 2
	colCounts["F"] = 2
	colCounts["G"] = 3
	for i, r := range strings.Split(testMatrix, "\n") {
		switch i {
		case 0:
			for _, cn := range strings.Split(r, ",") {
				if err := h.AddCol(cn, false); err != nil {
					t.Error(err)
				}
			}
		default:
			if len(r) > 0 {
				if err := h.AddRow(func(i int, n string) bool {
					if r[i] == '1' {
						return true
					}
					return false
				}); err != nil {
					t.Error(err)
				}
			}
		}
	}
	// asserts that the column counts are correct
	// not perfect, but a better test than many
	for n := h.rgt(); n != h; n = n.rgt() {
		if c, ok := n.(*column); ok {
			if c.count() != colCounts[c.label()] {
				t.Error(c)
			}
		}
	}
}
<commit_msg>Update test for `AddRow()`<commit_after>package goDLX

import (
	"strings"
	"testing"
)

// TestNew tests that creating a new Head actually does create a new Head.
// Nothing to verify other than a lack of errors.
func TestNew(t *testing.T) {
	h := New()
	if h == nil {
		t.Errorf("New(): Did not return a valid Head node")
	}
	if !assertCircleLft(h, 1) {
		t.Errorf("New(): Head not circular to the left")
	}
	if !assertCircleRgt(h, 1) {
		t.Errorf("New(): Head not circular to the right")
	}
}

func TestHeadLft(t *testing.T) {
	h := New()
	if lft := h.lft(); lft == nil {
		t.Errorf("Head.lft(): No node returned on left")
	}
}

func TestHeadSetLft(t *testing.T) {
	h := New()
	oh := new(Head)
	c := new(column)
	e := new(element)
	allowed := []node{h, c}
	forbidden := []node{oh, nil, e}
	for _, i := range allowed {
		if n, err := h.setLft(i); err != nil || n != i {
			t.Error(i)
		} else if !assertLft(h, i) {
			t.Error(i)
		}
	}
	for _, i := range forbidden {
		if n, err := h.setLft(i); err == nil || n != nil {
			t.Error(i)
		}
	}
}

func TestHeadRgt(t *testing.T) {
	h := New()
	if rgt := h.rgt(); rgt == nil {
		t.Errorf("Head.rgt(): No node returned on right")
	}
}

func TestHeadSetRgt(t *testing.T) {
	h := New()
	oh := new(Head)
	c := new(column)
	e := new(element)
	allowed := []node{h, c}
	forbidden := []node{oh, nil, e}
	for _, i := range allowed {
		if n, err := h.setRgt(i); err != nil || n != i {
			t.Error(i)
		} else if !assertRgt(h, i) {
			t.Error(i)
		}
	}
	for _, i := range forbidden {
		if n, err := h.setRgt(i); err == nil || n != nil {
			t.Error(i)
		}
	}
}

func TestHeadUp(t *testing.T) {
	h := New()
	if n := h.up(); n != h {
		t.Errorf("Head.up(): did not return self")
	}
}

func TestHeadSetUp(t *testing.T) {
	h := New()
	oh := new(Head)
	c := new(column)
	e := new(element)
	allowed := []node{}
	forbidden := []node{h, c, oh, e, nil}
	for _, i := range allowed {
		if n, err := h.setUp(i); err != nil || n != i {
			t.Error(i)
		} else if !assertUp(h, i) {
			t.Error(i)
		}
	}
	for _, i := range forbidden {
		if n, err := h.setUp(i); err == nil || n != nil {
			t.Error(i)
		}
	}
}

func TestHeadDn(t *testing.T) {
	h := New()
	if n := h.dn(); n != h {
		t.Errorf("Head.dn(): did not return self")
	}
}

func TestHeadSetDn(t *testing.T) {
	h := New()
	oh := new(Head)
	c := new(column)
	e := new(element)
	allowed := []node{}
	forbidden := []node{h, c, oh, e, nil}
	for _, i := range allowed {
		if n, err := h.setDn(i); err != nil || n != i {
			t.Error(i)
		} else if !assertDn(h, i) {
			t.Error(i)
		}
	}
	for _, i := range forbidden {
		if n, err := h.setDn(i); err == nil || n != nil {
			t.Error(i)
		}
	}
}

func TestHeadCol(t *testing.T) {
	h := New()
	if n := h.col(); n != h {
		t.Errorf("Head.col(): did not return self")
	}
}

func TestHeadAddCol(t *testing.T) {
	const colCount = 100
	h := New()
	for i := 0; i < colCount; i++ {
		h.AddCol(string(i), false)
		if !assertCircleLft(h, i+2) || !assertCircleRgt(h, i+2) {
			t.Errorf("Head.AddCol(name, optional): List no longer circular")
		}
	}
}

const testMatrix = `A,B,C,D,E,F,G
0010110
1001001
0110010
1001000
0100001
0001101
`
const solvedMatrix = `A,B,C,D,E,F,G
1001000
0100001
0010110
`

func TestHeadAddRow(t *testing.T) {
	h := New()
	// add the columns
	colCounts := make(map[string]int)
	cols := []string{}
	eRows := [][]bool{}
	rows := []bool{}
	for i, r := range strings.Split(testMatrix, "\n") {
		switch i {
		case 0:
			for _, cn := range strings.Split(r, ",") {
				// construct actual
				if err := h.AddCol(cn, false); err != nil {
					t.Error(err)
				}
				// construct expected
				colCounts[cn] = 0
				cols = append(cols, cn)
			}
		default:
			if len(r) > 0 {
				if err := h.AddRow(func(i int, n string) bool {
					if r[i] == '1' {
						colCounts[n]++
						return true
					}
					return false
				}); err != nil {
					t.Error(err)
				}
				newRow := []bool{}
				// construct expected
				for _, x := range r {
					if x == '1' {
						newRow = append(newRow, true)
					} else {
						newRow = append(newRow, false)
					}
				}
				eRows = append(eRows, newRow)
				rows = append(rows, false)
			}
		}
	}
	for n := h.rgt(); n != h; n = n.rgt() {
		if c, ok := n.(*column); ok {
			// asserts that the column counts are correct
			if c.count() != colCounts[c.label()] {
				t.Error(c)
			}
			// asserts that the rows exist
			// note that because of the way these are stored, it is
			// okay for a row to "exist" more than once
			for r, kk := c.dn().(*element); kk; r, kk = r.dn().(*element) {
				// construct the actual we can compare with
				aRow := []bool{}
				for _, cn := range cols {
					if r.colName() == cn {
						aRow = append(aRow, true)
					} else {
						hasCol := false
						for e, oo := r.rgt().(*element); oo && (e != r); e = e.rgt().(*element) {
							if e.colName() == cn {
								hasCol = true
								break
							}
						}
						aRow = append(aRow, hasCol)
					}
				}
				// find actual in expected
				rowExists := false
				for i := range eRows {
					rowsMatch := true
					for j := range eRows[i] {
						if eRows[i][j] != aRow[j] {
							rowsMatch = false
							break
						}
					}
					if rowsMatch {
						rows[i] = true
						rowExists = true
						break
					}
				}
				if !rowExists {
					t.Error(aRow)
				}
			}
		}
	}
	// assert that all expected rows exist
	for r := range rows {
		if !rows[r] {
			t.Error(eRows[r])
		}
	}
}
<|endoftext|>