<commit_before>package cv3go

// data structures for Orders
type ShipToProduct struct {
	SKU      string `xml:"SKU"`
	Quantity string `xml:"quantity"`
	Price    string `xml:"price"`
	Product  Product
}
type ShipTo struct {
	Name           string          `xml:"name"`
	FirstName      string          `xml:"firstName"`
	LastName       string          `xml:"lastName"`
	Company        string          `xml:"company"`
	Title          string          `xml:"title"`
	Address        string          `xml:"address1"`
	Address2       string          `xml:"address2"`
	City           string          `xml:"city"`
	State          string          `xml:"state"`
	Zip            string          `xml:"zip"`
	Country        string          `xml:"country"`
	Phone          string          `xml:"phone"`
	Tax            string          `xml:"tax"`
	Shipping       string          `xml:"shipping"`
	Message        string          `xml:"message"`
	ShipMethod     string          `xml:"shipMethod"`
	ShipMethodCode string          `xml:"shipMethodCode"`
	ShipOn         string          `xml:"shipOn"`
	GiftWrap       string          `xml:"giftWrap"`
	ShipToProducts []ShipToProduct `xml:"shipToProducts>shipToProduct"`
	ShipEmail      string          `xml:"shipEmail"`
}
type Order struct {
	SubTotal              string
	OrderID               string             `xml:"orderID"`
	PriceCategory         string             `xml:"priceCategory"`
	TotalPrice            string             `xml:"totalPrice"`
	TotalShipping         string             `xml:"totalShipping"`
	TotalTax              string             `xml:"totalTax"`
	DateOrdered           string             `xml:"dateOrdered"`
	TimeOrdered           string             `xml:"timeOrdered"`
	PayMethod             string             `xml:"payMethod"`
	SourceCode            string             `xml:"sourceCode"`
	PromoCode             string             `xml:"promoCode"`
	Comments              string             `xml:"comments"`
	IP                    string             `xml:"IP"`
	BillingCompany        string             `xml:"billing>company"`
	BillingFirstName      string             `xml:"billing>firstName"`
	BillingLastName       string             `xml:"billing>lastName"`
	BillingTitle          string             `xml:"billing>title"`
	BillingAddress        string             `xml:"billing>address1"`
	BillingAddress2       string             `xml:"billing>address2"`
	BillingCity           string             `xml:"billing>city"`
	BillingState          string             `xml:"billing>state"`
	BillingZip            string             `xml:"billing>zip"`
	BillingCountry        string             `xml:"billing>country"`
	BillingEmail          string             `xml:"billing>email"`
	BillingPhone          string             `xml:"billing>phone"`
	BillingOptOut         string             `xml:"billing>optOut"`
	BillingTransactionID  string             `xml:"billing>CCInfo>TransactionID"`
	MemberID              string             `xml:"billing>memberID"`
	CCType                string             `xml:"billing>CCInfo>CCType"`
	CCName                string             `xml:"billing>CCInfo>CCName"`
	CCNum                 string             `xml:"billing>CCInfo>CCNum"`
	CCExpM                string             `xml:"billing>CCInfo>CCExpM"`
	CCExpY                string             `xml:"billing>CCInfo>CCExpY"`
	AuthCode              string             `xml:"billing>CCInfo>authCode"`
	AuthAmount            string             `xml:"billing>CCInfo>authAmount"`
	RequestToken          string             `xml:"billing>CCInfo>token"`
	PurchaseOrder         string             `xml:"purchaseOrder"`
	PayPalBuyer           string             `xml:"payPalInfo>Buyer"`
	PayPalAmount          string             `xml:"payPalInfo>Amount"`
	PayPalTransactionID   string             `xml:"payPalInfo>TransactionID"`
	ShipTos               []ShipTo           `xml:"shipTos>shipTo"`
	CustomFields          []CustomField      `xml:"customFields>customField"`
	TotalOrderDiscount    TotalOrderDiscount `xml:"totalOrderDiscount"`
	GiftCardPayments      []GiftCardPayment  `xml:"billing>GCInfo>giftCertificateUsed"`
	GiftCardPaymentsTotal string             `xml:"billing>GCInfo>totalAmountUsed"`
}

type GiftCardPayment struct {
	Certificate string `xml:"giftCertificate"`
	Amount      string `xml:"amountUsed"`
}

type TotalOrderDiscount struct {
	Amount        string `xml:"amount"`
	TotalDiscount string `xml:"totalDiscount"`
	Type          string `xml:"type,attr"`
}

type Price struct {
}

type Orders struct {
	Orders []Order `xml:"orders>order"`
}

type CustomField struct {
	Value string `xml:",innerxml"`
}
<commit_msg>Case sensitive xml fix<commit_after>package cv3go

// data structures for Orders
type ShipToProduct struct {
	SKU      string `xml:"SKU"`
	Quantity string `xml:"quantity"`
	Price    string `xml:"price"`
	Product  Product
}
type ShipTo struct {
	Name           string          `xml:"name"`
	FirstName      string          `xml:"firstName"`
	LastName       string          `xml:"lastName"`
	Company        string          `xml:"company"`
	Title          string          `xml:"title"`
	Address        string          `xml:"address1"`
	Address2       string          `xml:"address2"`
	City           string          `xml:"city"`
	State          string          `xml:"state"`
	Zip            string          `xml:"zip"`
	Country        string          `xml:"country"`
	Phone          string          `xml:"phone"`
	Tax            string          `xml:"tax"`
	Shipping       string          `xml:"shipping"`
	Message        string          `xml:"message"`
	ShipMethod     string          `xml:"shipMethod"`
	ShipMethodCode string          `xml:"shipMethodCode"`
	ShipOn         string          `xml:"shipOn"`
	GiftWrap       string          `xml:"giftWrap"`
	ShipToProducts []ShipToProduct `xml:"shipToProducts>shipToProduct"`
	ShipEmail      string          `xml:"shipEmail"`
}
type Order struct {
	SubTotal              string
	OrderID               string             `xml:"orderID"`
	PriceCategory         string             `xml:"priceCategory"`
	TotalPrice            string             `xml:"totalPrice"`
	TotalShipping         string             `xml:"totalShipping"`
	TotalTax              string             `xml:"totalTax"`
	DateOrdered           string             `xml:"dateOrdered"`
	TimeOrdered           string             `xml:"timeOrdered"`
	PayMethod             string             `xml:"payMethod"`
	SourceCode            string             `xml:"sourceCode"`
	PromoCode             string             `xml:"promoCode"`
	Comments              string             `xml:"comments"`
	IP                    string             `xml:"IP"`
	BillingCompany        string             `xml:"billing>company"`
	BillingFirstName      string             `xml:"billing>firstName"`
	BillingLastName       string             `xml:"billing>lastName"`
	BillingTitle          string             `xml:"billing>title"`
	BillingAddress        string             `xml:"billing>address1"`
	BillingAddress2       string             `xml:"billing>address2"`
	BillingCity           string             `xml:"billing>city"`
	BillingState          string             `xml:"billing>state"`
	BillingZip            string             `xml:"billing>zip"`
	BillingCountry        string             `xml:"billing>country"`
	BillingEmail          string             `xml:"billing>email"`
	BillingPhone          string             `xml:"billing>phone"`
	BillingOptOut         string             `xml:"billing>optOut"`
	BillingTransactionID  string             `xml:"billing>CCInfo>transactionID"`
	MemberID              string             `xml:"billing>memberID"`
	CCType                string             `xml:"billing>CCInfo>CCType"`
	CCName                string             `xml:"billing>CCInfo>CCName"`
	CCNum                 string             `xml:"billing>CCInfo>CCNum"`
	CCExpM                string             `xml:"billing>CCInfo>CCExpM"`
	CCExpY                string             `xml:"billing>CCInfo>CCExpY"`
	AuthCode              string             `xml:"billing>CCInfo>authCode"`
	AuthAmount            string             `xml:"billing>CCInfo>authAmount"`
	RequestToken          string             `xml:"billing>CCInfo>token"`
	PurchaseOrder         string             `xml:"purchaseOrder"`
	PayPalBuyer           string             `xml:"payPalInfo>Buyer"`
	PayPalAmount          string             `xml:"payPalInfo>Amount"`
	PayPalTransactionID   string             `xml:"payPalInfo>TransactionID"`
	ShipTos               []ShipTo           `xml:"shipTos>shipTo"`
	CustomFields          []CustomField      `xml:"customFields>customField"`
	TotalOrderDiscount    TotalOrderDiscount `xml:"totalOrderDiscount"`
	GiftCardPayments      []GiftCardPayment  `xml:"billing>GCInfo>giftCertificateUsed"`
	GiftCardPaymentsTotal string             `xml:"billing>GCInfo>totalAmountUsed"`
}

type GiftCardPayment struct {
	Certificate string `xml:"giftCertificate"`
	Amount      string `xml:"amountUsed"`
}

type TotalOrderDiscount struct {
	Amount        string `xml:"amount"`
	TotalDiscount string `xml:"totalDiscount"`
	Type          string `xml:"type,attr"`
}

type Price struct {
}

type Orders struct {
	Orders []Order `xml:"orders>order"`
}

type CustomField struct {
	Value string `xml:",innerxml"`
}
<|endoftext|>


<commit_before>package market

import (
	"bytes"
	"context"
	"encoding/base64"
	"encoding/json"
	"io/ioutil"
	"net/http"
	"net/url"

	"github.com/greater-commons/paypal-marketplace/orders"
)

const (
	createOrderRoute           = "/v1/checkout/orders"
	getTransactionContextRoute = "/v1/risk/transaction-contexts"
	disbursePaymentsRoute      = "/v1/payments/referenced-payouts-items"
	requestRefundRoute         = "/v1/payments/capture/"
)

func (c *Client) CreateOrder(ctx context.Context, params *orders.CreateOrderParams) (*orders.CreateOrderResponse, error) {
	d, err := json.Marshal(params)
	if err != nil {
		return nil, err
	}
	r := &request{
		client:   c,
		method:   http.MethodPost,
		endpoint: createOrderRoute,
		body:     bytes.NewReader(d),
	}
	res, err := r.do(ctx)
	if err != nil {
		return nil, err
	}
	if res.status == http.StatusCreated {
		r := &orders.CreateOrderResponse{}
		err = json.NewDecoder(res.body).Decode(r)
		if err != nil {
			return nil, err
		}
		return r, nil
	}
	errorData, err := ioutil.ReadAll(res.body)
	if err != nil {
		return nil, err
	}
	return nil, &BadResponse{
		Status: res.status,
		Body:   string(errorData),
	}
}

func (c *Client) CancelOrder(ctx context.Context, orderID string) error {
	r := &request{
		client:   c,
		method:   http.MethodDelete,
		endpoint: createOrderRoute + "/" + url.PathEscape(orderID),
	}
	res, err := r.do(ctx)
	if err != nil {
		return err
	}
	if res.status == http.StatusNoContent {
		return nil
	}
	errorData, err := ioutil.ReadAll(res.body)
	if err != nil {
		return err
	}
	return &BadResponse{
		Status: res.status,
		Body:   string(errorData),
	}
}

func (c *Client) GetOrderDetails(ctx context.Context, orderID string) (*orders.CreateOrderResponse, error) {
	r := &request{
		client:   c,
		method:   http.MethodGet,
		endpoint: createOrderRoute + "/" + url.PathEscape(orderID),
	}
	res, err := r.do(ctx)
	if err != nil {
		return nil, err
	}
	if res.status == http.StatusOK {
		r := &orders.CreateOrderResponse{}
		err := json.NewDecoder(res.body).Decode(r)
		if err != nil {
			return nil, err
		}
		return r, nil
	}
	errorData, err := ioutil.ReadAll(res.body)
	if err != nil {
		return nil, err
	}
	return nil, &BadResponse{
		Status: res.status,
		Body:   string(errorData),
	}
}

func (c *Client) SaveTransactionContext(ctx context.Context, merchantID, trackingID string, additionalData []orders.KeyValuePair) error {
	body := struct {
		AdditionalData []orders.KeyValuePair `json:"additional_data,omitempty"`
	}{
		AdditionalData: additionalData,
	}
	d, err := json.Marshal(&body)
	if err != nil {
		return err
	}
	r := &request{
		client:   c,
		method:   http.MethodPut,
		endpoint: getTransactionContextRoute + "/" + url.PathEscape(merchantID) + "/" + url.PathEscape(trackingID),
		body:     bytes.NewReader(d),
	}
	res, err := r.do(ctx)
	if err != nil {
		return err
	}
	if res.status == http.StatusOK {
		return nil
	}
	errorData, err := ioutil.ReadAll(res.body)
	if err != nil {
		return err
	}
	return &BadResponse{
		Status: res.status,
		Body:   string(errorData),
	}
}

func (c *Client) PayOrder(ctx context.Context, orderID string, disbursementMode orders.DisbursementModeData) (*orders.PayOrderResponse, error) {
	data := struct {
		DisbursementMode orders.DisbursementModeData `json:"disbursement_mode"`
	}{
		DisbursementMode: disbursementMode,
	}
	d, err := json.Marshal(&data)
	if err != nil {
		return nil, err
	}
	r := &request{
		client:   c,
		method:   http.MethodPost,
		endpoint: createOrderRoute + "/" + url.PathEscape(orderID) + "/pay",
		body:     bytes.NewReader(d),
	}
	res, err := r.do(ctx)
	if err != nil {
		return nil, err
	}
	if res.status >= 200 && res.status < 300 {
		r := &orders.PayOrderResponse{}
		err = json.NewDecoder(res.body).Decode(r)
		if err != nil {
			return nil, err
		}
		return r, nil
	}

	errorData, err := ioutil.ReadAll(res.body)
	if err != nil {
		return nil, err
	}
	return nil, &BadResponse{
		Status: res.status,
		Body:   string(errorData),
	}
}

func (c *Client) FinalizeDisbursement(ctx context.Context, responsePreference orders.ResponsePreferenceData, transactionID string) (*orders.FinalizeDisbursementResponse, error) {
	data := struct {
		ReferenceID   string `json:"reference_id"`
		ReferenceType string `json:"reference_type"`
	}{
		ReferenceID:   transactionID,
		ReferenceType: "TRANSACTION_ID",
	}
	d, err := json.Marshal(&data)
	if err != nil {
		return nil, err
	}
	r := &request{
		client:   c,
		method:   http.MethodPost,
		endpoint: disbursePaymentsRoute,
		body:     bytes.NewReader(d),
		headers: map[string][]string{
			"Prefer": []string{string(responsePreference)},
		},
	}
	res, err := r.do(ctx)
	if err != nil {
		return nil, err
	}
	if res.status == http.StatusOK {
		r := &orders.FinalizeDisbursementResponse{}
		err = json.NewDecoder(res.body).Decode(r)
		if err != nil {
			return nil, err
		}
		return r, nil
	}

	errorData, err := ioutil.ReadAll(res.body)
	if err != nil {
		return nil, err
	}
	return nil, &BadResponse{
		Status: res.status,
		Body:   string(errorData),
	}
}

func (c *Client) RequestRefund(ctx context.Context, captureID, clientID, payerID string, params *orders.RequestRefundParams) (*orders.RequestRefundResponse, error) {
	d, err := json.Marshal(params)
	if err != nil {
		return nil, err
	}
	authHeader := base64.StdEncoding.EncodeToString([]byte(`{"alg":"none"}`)) + "." + base64.StdEncoding.EncodeToString([]byte(`{"iss":"`+clientID+`","payer_id":"`+payerID+`"}`)) + "."
	r := &request{
		client:   c,
		method:   http.MethodPost,
		endpoint: requestRefundRoute + captureID + "/refund",
		body:     bytes.NewReader(d),
		headers: map[string][]string{
			"PayPal-Auth-Assertion": []string{authHeader},
		},
	}
	res, err := r.do(ctx)
	if err != nil {
		return nil, err
	}
	if res.status == http.StatusCreated {
		r := &orders.RequestRefundResponse{}
		err = json.NewDecoder(res.body).Decode(r)
		if err != nil {
			return nil, err
		}
		return r, nil
	}
	errorData, err := ioutil.ReadAll(res.body)
	if err != nil {
		return nil, err
	}
	return nil, &BadResponse{
		Status: res.status,
		Body:   string(errorData),
	}
}
<commit_msg>Allow created status code in disburse payments<commit_after>package market

import (
	"bytes"
	"context"
	"encoding/base64"
	"encoding/json"
	"io/ioutil"
	"net/http"
	"net/url"

	"github.com/greater-commons/paypal-marketplace/orders"
)

const (
	createOrderRoute           = "/v1/checkout/orders"
	getTransactionContextRoute = "/v1/risk/transaction-contexts"
	disbursePaymentsRoute      = "/v1/payments/referenced-payouts-items"
	requestRefundRoute         = "/v1/payments/capture/"
)

func (c *Client) CreateOrder(ctx context.Context, params *orders.CreateOrderParams) (*orders.CreateOrderResponse, error) {
	d, err := json.Marshal(params)
	if err != nil {
		return nil, err
	}
	r := &request{
		client:   c,
		method:   http.MethodPost,
		endpoint: createOrderRoute,
		body:     bytes.NewReader(d),
	}
	res, err := r.do(ctx)
	if err != nil {
		return nil, err
	}
	if res.status == http.StatusCreated {
		r := &orders.CreateOrderResponse{}
		err = json.NewDecoder(res.body).Decode(r)
		if err != nil {
			return nil, err
		}
		return r, nil
	}
	errorData, err := ioutil.ReadAll(res.body)
	if err != nil {
		return nil, err
	}
	return nil, &BadResponse{
		Status: res.status,
		Body:   string(errorData),
	}
}

func (c *Client) CancelOrder(ctx context.Context, orderID string) error {
	r := &request{
		client:   c,
		method:   http.MethodDelete,
		endpoint: createOrderRoute + "/" + url.PathEscape(orderID),
	}
	res, err := r.do(ctx)
	if err != nil {
		return err
	}
	if res.status == http.StatusNoContent {
		return nil
	}
	errorData, err := ioutil.ReadAll(res.body)
	if err != nil {
		return err
	}
	return &BadResponse{
		Status: res.status,
		Body:   string(errorData),
	}
}

func (c *Client) GetOrderDetails(ctx context.Context, orderID string) (*orders.CreateOrderResponse, error) {
	r := &request{
		client:   c,
		method:   http.MethodGet,
		endpoint: createOrderRoute + "/" + url.PathEscape(orderID),
	}
	res, err := r.do(ctx)
	if err != nil {
		return nil, err
	}
	if res.status == http.StatusOK {
		r := &orders.CreateOrderResponse{}
		err := json.NewDecoder(res.body).Decode(r)
		if err != nil {
			return nil, err
		}
		return r, nil
	}
	errorData, err := ioutil.ReadAll(res.body)
	if err != nil {
		return nil, err
	}
	return nil, &BadResponse{
		Status: res.status,
		Body:   string(errorData),
	}
}

func (c *Client) SaveTransactionContext(ctx context.Context, merchantID, trackingID string, additionalData []orders.KeyValuePair) error {
	body := struct {
		AdditionalData []orders.KeyValuePair `json:"additional_data,omitempty"`
	}{
		AdditionalData: additionalData,
	}
	d, err := json.Marshal(&body)
	if err != nil {
		return err
	}
	r := &request{
		client:   c,
		method:   http.MethodPut,
		endpoint: getTransactionContextRoute + "/" + url.PathEscape(merchantID) + "/" + url.PathEscape(trackingID),
		body:     bytes.NewReader(d),
	}
	res, err := r.do(ctx)
	if err != nil {
		return err
	}
	if res.status == http.StatusOK {
		return nil
	}
	errorData, err := ioutil.ReadAll(res.body)
	if err != nil {
		return err
	}
	return &BadResponse{
		Status: res.status,
		Body:   string(errorData),
	}
}

func (c *Client) PayOrder(ctx context.Context, orderID string, disbursementMode orders.DisbursementModeData) (*orders.PayOrderResponse, error) {
	data := struct {
		DisbursementMode orders.DisbursementModeData `json:"disbursement_mode"`
	}{
		DisbursementMode: disbursementMode,
	}
	d, err := json.Marshal(&data)
	if err != nil {
		return nil, err
	}
	r := &request{
		client:   c,
		method:   http.MethodPost,
		endpoint: createOrderRoute + "/" + url.PathEscape(orderID) + "/pay",
		body:     bytes.NewReader(d),
	}
	res, err := r.do(ctx)
	if err != nil {
		return nil, err
	}
	if res.status >= 200 && res.status < 300 {
		r := &orders.PayOrderResponse{}
		err = json.NewDecoder(res.body).Decode(r)
		if err != nil {
			return nil, err
		}
		return r, nil
	}

	errorData, err := ioutil.ReadAll(res.body)
	if err != nil {
		return nil, err
	}
	return nil, &BadResponse{
		Status: res.status,
		Body:   string(errorData),
	}
}

func (c *Client) FinalizeDisbursement(ctx context.Context, responsePreference orders.ResponsePreferenceData, transactionID string) (*orders.FinalizeDisbursementResponse, error) {
	data := struct {
		ReferenceID   string `json:"reference_id"`
		ReferenceType string `json:"reference_type"`
	}{
		ReferenceID:   transactionID,
		ReferenceType: "TRANSACTION_ID",
	}
	d, err := json.Marshal(&data)
	if err != nil {
		return nil, err
	}
	r := &request{
		client:   c,
		method:   http.MethodPost,
		endpoint: disbursePaymentsRoute,
		body:     bytes.NewReader(d),
		headers: map[string][]string{
			"Prefer": []string{string(responsePreference)},
		},
	}
	res, err := r.do(ctx)
	if err != nil {
		return nil, err
	}
	if res.status == http.StatusOK || res.status == http.StatusCreated {
		r := &orders.FinalizeDisbursementResponse{}
		err = json.NewDecoder(res.body).Decode(r)
		if err != nil {
			return nil, err
		}
		return r, nil
	}

	errorData, err := ioutil.ReadAll(res.body)
	if err != nil {
		return nil, err
	}
	return nil, &BadResponse{
		Status: res.status,
		Body:   string(errorData),
	}
}

func (c *Client) RequestRefund(ctx context.Context, captureID, clientID, payerID string, params *orders.RequestRefundParams) (*orders.RequestRefundResponse, error) {
	d, err := json.Marshal(params)
	if err != nil {
		return nil, err
	}
	authHeader := base64.StdEncoding.EncodeToString([]byte(`{"alg":"none"}`)) + "." + base64.StdEncoding.EncodeToString([]byte(`{"iss":"`+clientID+`","payer_id":"`+payerID+`"}`)) + "."
	r := &request{
		client:   c,
		method:   http.MethodPost,
		endpoint: requestRefundRoute + captureID + "/refund",
		body:     bytes.NewReader(d),
		headers: map[string][]string{
			"PayPal-Auth-Assertion": []string{authHeader},
		},
	}
	res, err := r.do(ctx)
	if err != nil {
		return nil, err
	}
	if res.status == http.StatusCreated {
		r := &orders.RequestRefundResponse{}
		err = json.NewDecoder(res.body).Decode(r)
		if err != nil {
			return nil, err
		}
		return r, nil
	}
	errorData, err := ioutil.ReadAll(res.body)
	if err != nil {
		return nil, err
	}
	return nil, &BadResponse{
		Status: res.status,
		Body:   string(errorData),
	}
}
<|endoftext|>


<commit_before>package effio

/*
 * Copyright 2014 Albert P. Tobey <atobey@datastax.com> @AlTobey
 *
 * 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.
 */

import (
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"os"
	"path/filepath"
	"strings"
)

func (cmd *Cmd) ServeHTTP() {
	var addrFlag string

	cmd.DefaultFlags()
	cmd.FlagSet.StringVar(&addrFlag, "addr", ":9000", "IP:PORT or :PORT address to listen on")
	cmd.ParseArgs()

	if cmd.PathFlag == "" {
		cmd.PathFlag = "public/data"
	}

	http.HandleFunc("/inventory", cmd.InventoryDataHandler)
	http.Handle("/", http.FileServer(http.Dir("./public")))

	err := http.ListenAndServe(addrFlag, nil)
	if err != nil {
		log.Fatalf("net.http could not listen on address '%s': %s\n", addrFlag, err)
	}
}

func (cmd *Cmd) InventoryDataHandler(w http.ResponseWriter, r *http.Request) {
	items := InventoryData(cmd.PathFlag)

	json, err := json.Marshal(items)
	if err != nil {
		log.Printf("JSON marshal failed: %s\n", err)
		http.Error(w, fmt.Sprintf("Marshaling JSON failed: %s", err), 500)
	}

	w.Write(json)
}

func InventoryData(dpath string) []string {
	out := make([]string, 0)

	visitor := func(dpath string, f os.FileInfo, err error) error {
		if err != nil {
			log.Fatalf("Encountered an error while inventorying data in '%s': %s", dpath, err)
		}

		if strings.HasSuffix(dpath, ".json") {
			out = append(out, strings.TrimPrefix(dpath, "public"))
		}

		return nil
	}

	err := filepath.Walk(dpath, visitor)
	if err != nil {
		log.Fatalf("Could not inventory suites in '%s': %s", dpath, err)
	}

	return out
}
<commit_msg>separate logs by logtype<commit_after>package effio

/*
 * Copyright 2014 Albert P. Tobey <atobey@datastax.com> @AlTobey
 *
 * 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.
 */

import (
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"os"
	"path/filepath"
	"strings"
)

func (cmd *Cmd) ServeHTTP() {
	var addrFlag string

	cmd.DefaultFlags()
	cmd.FlagSet.StringVar(&addrFlag, "addr", ":9000", "IP:PORT or :PORT address to listen on")
	cmd.ParseArgs()

	if cmd.PathFlag == "" {
		cmd.PathFlag = "public/data"
	}

	http.HandleFunc("/inventory", cmd.InventoryDataHandler)
	http.Handle("/", http.FileServer(http.Dir("./public")))

	err := http.ListenAndServe(addrFlag, nil)
	if err != nil {
		log.Fatalf("net.http could not listen on address '%s': %s\n", addrFlag, err)
	}
}

func (cmd *Cmd) InventoryDataHandler(w http.ResponseWriter, r *http.Request) {
	files := InventoryData(cmd.PathFlag)

	// separate logfiles by log type
	// there are 5 log types (for now)
	out := make(map[string][]string, 5)
	for _, file := range files {
		base := strings.TrimSuffix(file, ".json")
		logtype := strings.Split(base, "-")[1]

		if _, ok := out[logtype]; !ok {
			out[logtype] = make([]string, 0)
		}
		out[logtype] = append(out[logtype], file)
	}

	json, err := json.Marshal(out)
	if err != nil {
		log.Printf("JSON marshal failed: %s\n", err)
		http.Error(w, fmt.Sprintf("Marshaling JSON failed: %s", err), 500)
	}

	w.Write(json)
}

func InventoryData(dpath string) []string {
	out := make([]string, 0)

	visitor := func(dpath string, f os.FileInfo, err error) error {
		if err != nil {
			log.Fatalf("Encountered an error while inventorying data in '%s': %s", dpath, err)
		}

		if strings.HasSuffix(dpath, ".json") {
			out = append(out, strings.TrimPrefix(dpath, "public"))
		}

		return nil
	}

	err := filepath.Walk(dpath, visitor)
	if err != nil {
		log.Fatalf("Could not inventory suites in '%s': %s", dpath, err)
	}

	return out
}
<|endoftext|>


<commit_before>package egoscale

import (
	"encoding/json"
	"net/url"
	"fmt"
)

func (exo *Client) CreateEgressRule(rule SecurityGroupRule) (*AuthorizeSecurityGroupEgressResponse, error) {

	params := url.Values{}
	params.Set("securitygroupid", rule.SecurityGroupId)
	params.Set("cidrlist", rule.Cidr)
	params.Set("protocol", rule.Protocol)

	if (rule.Protocol == "ICMP") {
		params.Set("icmpcode", fmt.Sprintf("%d", rule.IcmpCode))
		params.Set("icmptype", fmt.Sprintf("%d", rule.IcmpType))
	} else {
		params.Set("startport", fmt.Sprintf("%d", rule.Port))
		params.Set("endport", fmt.Sprintf("%d", rule.Port))
	}

	resp, err := exo.Request("authorizeSecurityGroupEgress", params)
	if err != nil {
		return nil, err
	}

	var r AuthorizeSecurityGroupEgressResponse
	if err := json.Unmarshal(resp, &r); err != nil {
		return nil, err
	}

	return &r, nil
}

func (exo *Client) CreateIngressRule(rule SecurityGroupRule) (*AuthorizeSecurityGroupIngressResponse, error) {

	params := url.Values{}
	params.Set("securitygroupid", rule.SecurityGroupId)
	params.Set("cidrlist", rule.Cidr)
	params.Set("protocol", rule.Protocol)

	if (rule.Protocol == "icmp") {
		params.Set("icmpcode", fmt.Sprintf("%d", rule.IcmpCode))
		params.Set("icmptype", fmt.Sprintf("%d", rule.IcmpType))
	} else {
		params.Set("startport", fmt.Sprintf("%d", rule.Port))
		params.Set("endport", fmt.Sprintf("%d", rule.Port))
	}

	resp, err := exo.Request("authorizeSecurityGroupIngress", params)

	if err != nil {
		return nil, err
	}

	var r AuthorizeSecurityGroupIngressResponse
	if err := json.Unmarshal(resp, &r); err != nil {
		return nil, err
	}

	return &r, nil
}

func (exo *Client) CreateSecurityGroupWithRules(name string, ingress []SecurityGroupRule, egress []SecurityGroupRule) (*CreateSecurityGroupResponse, error) {

	params := url.Values{}
	params.Set("name", name)

	resp, err := exo.Request("createSecurityGroup", params)

	var r CreateSecurityGroupResponseWrapper
	if err := json.Unmarshal(resp, &r); err != nil {
		return nil, err
	}

	if err != nil {
		return nil, err
	}

	sgid := r.Wrapped.Id

	for _, erule := range(egress) {
		erule.SecurityGroupId = sgid
		_, err = exo.CreateEgressRule(erule)
		if (err != nil) {
			return nil, err
		}
	}

	for _, inrule := range(ingress) {
		inrule.SecurityGroupId = sgid
		fmt.Printf("group ID: %s\n", inrule.SecurityGroupId)
		_, err = exo.CreateIngressRule(inrule)
		if (err != nil) {
			return nil, err
		}
	}

	return &r.Wrapped, nil
}
<commit_msg>sanitize input<commit_after>package egoscale

import (
	"encoding/json"
	"net/url"
	"fmt"
)

func (exo *Client) CreateEgressRule(rule SecurityGroupRule) (*AuthorizeSecurityGroupEgressResponse, error) {

	params := url.Values{}
	params.Set("securitygroupid", rule.SecurityGroupId)
	params.Set("cidrlist", rule.Cidr)
	params.Set("protocol", rule.Protocol)

	if rule.Protocol == "ICMP" {
		params.Set("icmpcode", fmt.Sprintf("%d", rule.IcmpCode))
		params.Set("icmptype", fmt.Sprintf("%d", rule.IcmpType))
	} else if (rule.Protocol == "TCP" || rule.Protocol == "UDP") {
		params.Set("startport", fmt.Sprintf("%d", rule.Port))
		params.Set("endport", fmt.Sprintf("%d", rule.Port))
	} else {
		return nil, fmt.Errorf("Invalid Egress rule Protocol: %s", rule.Protocol)
	}

	resp, err := exo.Request("authorizeSecurityGroupEgress", params)
	if err != nil {
		return nil, err
	}

	var r AuthorizeSecurityGroupEgressResponse
	if err := json.Unmarshal(resp, &r); err != nil {
		return nil, err
	}

	return &r, nil
}

func (exo *Client) CreateIngressRule(rule SecurityGroupRule) (*AuthorizeSecurityGroupIngressResponse, error) {

	params := url.Values{}
	params.Set("securitygroupid", rule.SecurityGroupId)
	params.Set("cidrlist", rule.Cidr)
	params.Set("protocol", rule.Protocol)

	if rule.Protocol == "ICMP" {
		params.Set("icmpcode", fmt.Sprintf("%d", rule.IcmpCode))
		params.Set("icmptype", fmt.Sprintf("%d", rule.IcmpType))
	} else if (rule.Protocol == "TCP" || rule.Protocol == "UDP") {
		params.Set("startport", fmt.Sprintf("%d", rule.Port))
		params.Set("endport", fmt.Sprintf("%d", rule.Port))
	} else {
		return nil, fmt.Errorf("Invalid Egress rule Protocol: %s", rule.Protocol)
	}

	resp, err := exo.Request("authorizeSecurityGroupIngress", params)

	if err != nil {
		return nil, err
	}

	var r AuthorizeSecurityGroupIngressResponse
	if err := json.Unmarshal(resp, &r); err != nil {
		return nil, err
	}

	return &r, nil
}

func (exo *Client) CreateSecurityGroupWithRules(name string, ingress []SecurityGroupRule, egress []SecurityGroupRule) (*CreateSecurityGroupResponse, error) {

	params := url.Values{}
	params.Set("name", name)

	resp, err := exo.Request("createSecurityGroup", params)

	var r CreateSecurityGroupResponseWrapper
	if err := json.Unmarshal(resp, &r); err != nil {
		return nil, err
	}

	if err != nil {
		return nil, err
	}

	sgid := r.Wrapped.Id

	for _, erule := range(egress) {
		erule.SecurityGroupId = sgid
		_, err = exo.CreateEgressRule(erule)
		if (err != nil) {
			return nil, err
		}
	}

	for _, inrule := range(ingress) {
		inrule.SecurityGroupId = sgid
		fmt.Printf("group ID: %s\n", inrule.SecurityGroupId)
		_, err = exo.CreateIngressRule(inrule)
		if (err != nil) {
			return nil, err
		}
	}

	return &r.Wrapped, nil
}
<|endoftext|>


<commit_before>package godbg

import (
	"fmt"
	"os"
	"runtime"
	"testing"
	. "github.com/smartystreets/goconvey/convey"
)

func TestProject(t *testing.T) {
	SkipConvey("Test buffers", t, func() {

		Convey("By Default, equals to std", func() {
			So(Out(), ShouldEqual, os.Stdout)
			So(Err(), ShouldEqual, os.Stderr)
		})
		Convey("When set to buffer, no longer equals to std", func() {
			SetBuffers(nil)
			So(Out(), ShouldNotEqual, os.Stdout)
			So(Err(), ShouldNotEqual, os.Stderr)
		})
		Convey("By Default, a new pdbg instance buffer equals to std", func() {
			apdbg := NewPdbg()
			So(apdbg.Out(), ShouldEqual, os.Stdout)
			So(apdbg.Err(), ShouldEqual, os.Stderr)
		})
		Convey("By Default, a new pdbg instance set to buffer writes no longer equals to std", func() {
			apdbg := NewPdbg(SetBuffers)
			So(apdbg.Out(), ShouldNotEqual, os.Stdout)
			So(apdbg.Err(), ShouldNotEqual, os.Stderr)
		})
		Convey("Test custom buffer on global pdbg", func() {
			pdbg.bout = nil
			pdbg.sout = nil
			pdbg.berr = nil
			pdbg.serr = nil
			fmt.Fprintln(Out(), "test0 content0")
			So(OutString(), ShouldEqual, ``)
			fmt.Fprintln(Err(), "err0 content0")
			So(ErrString(), ShouldEqual, ``)
			SetBuffers(nil)
			fmt.Fprintln(Out(), "test content")
			fmt.Fprintln(Err(), "err1 cerr")
			fmt.Fprintln(Err(), "err2 cerr2")
			fmt.Fprint(Out(), "test2 content2")
			So(OutString(), ShouldEqual, `test content
test2 content2`)
			So(ErrString(), ShouldEqual, `err1 cerr
err2 cerr2
`)
		})

		Convey("Test custom buffer reset on global pdbg", func() {
			SetBuffers(nil)
			fmt.Fprint(Out(), "test content")
			So(OutString(), ShouldEqual, `test content`)
			fmt.Fprint(Err(), "err1 cerr")
			So(ErrString(), ShouldEqual, `err1 cerr`)
			ResetIOs()
			fmt.Fprint(Out(), "test2 content2")
			So(OutString(), ShouldEqual, `test2 content2`)
			fmt.Fprint(Err(), "err2 cerr2")
			So(ErrString(), ShouldEqual, `err2 cerr2`)
		})

		Convey("Test custom buffer on custom pdbg", func() {
			apdbg := NewPdbg(SetBuffers)
			fmt.Fprintln(apdbg.Out(), "test content")
			fmt.Fprintln(apdbg.Err(), "err1 cerr")
			fmt.Fprintln(apdbg.Err(), "err2 cerr2")
			fmt.Fprint(apdbg.Out(), "test2 content2")
			So(apdbg.OutString(), ShouldEqual, `test content
test2 content2`)
			So(apdbg.ErrString(), ShouldEqual, `err1 cerr
err2 cerr2
`)
		})
		Convey("Test custom buffer reset on custom pdbg", func() {
			apdbg := NewPdbg(SetBuffers)
			fmt.Fprint(apdbg.Out(), "test content")
			So(apdbg.OutString(), ShouldEqual, `test content`)
			fmt.Fprint(apdbg.Err(), "err1 cerr")
			So(apdbg.ErrString(), ShouldEqual, `err1 cerr`)
			apdbg.ResetIOs()
			fmt.Fprint(apdbg.Out(), "test2 content2")
			So(apdbg.OutString(), ShouldEqual, `test2 content2`)
			fmt.Fprint(apdbg.Err(), "err2 cerr2")
			So(apdbg.ErrString(), ShouldEqual, `err2 cerr2`)
		})
	})

	SkipConvey("Test pdbg print functions", t, func() {
		Convey("Test pdbg print with global instance", func() {
			SetBuffers(nil)
			Pdbgf("test")
			So(ErrString(), ShouldEqual,
				`[func.012:96]
  test
`)
			ResetIOs()
			prbgtest()
			So(ErrString(), ShouldEqual,
				` [prbgtest:4] (func.012:102)
   prbgtest content
`)
		})

		Convey("Test pdbg print with custom instance", func() {
			apdbg := NewPdbg(SetBuffers)
			apdbg.Pdbgf("test2")
			So(apdbg.ErrString(), ShouldEqual,
				`[func.013:111]
  test2
`)
			apdbg.ResetIOs()
			prbgtestCustom(apdbg)
			So(apdbg.ErrString(), ShouldEqual,
				` [prbgtestCustom:8] (func.013:117)
   prbgtest content2
`)
			apdbg.ResetIOs()
			apdbg.pdbgTestInstance()
			So(apdbg.ErrString(), ShouldEqual,
				` [*Pdbg.pdbgTestInstance:12] (func.013:123)
   pdbgTestInstance content3
`)
		})
		Convey("Test pdbg prints nothing if runtime.Caller fails", func() {
			mycaller = failCaller
			apdbg := NewPdbg(SetBuffers)
			apdbg.Pdbgf("test fail")
			So(apdbg.ErrString(), ShouldEqual, `  test fail
`)
			mycaller = runtime.Caller
		})
	})

	SkipConvey("Test pdbg excludes functions", t, func() {
		Convey("Test pdbg exclude with global instance", func() {
			SetBuffers(nil)
			pdbg.SetExcludes([]string{"globalNo"})
			globalPdbgExcludeTest()
			So(ErrString(), ShouldEqual,
				` [globalPdbgExcludeTest:16] (func.016:143)
   calling no
   [globalCNo:26] (globalPdbgExcludeTest:17) (func.016:143)
     gcalled2
`)
		})
		Convey("Test pdbg exclude with custom instance", func() {
			apdbg := NewPdbg(SetBuffers, OptExcludes([]string{"customNo"}))
			customPdbgExcludeTest(apdbg)
			So(apdbg.ErrString(), ShouldEqual,
				` [customPdbgExcludeTest:30] (func.017:153)
   calling cno
   [customCNo:40] (customPdbgExcludeTest:31) (func.017:153)
     ccalled2
`)
		})
	})

	Convey("Test pdbg skips functions", t, func() {
		Convey("Test pdbg skip with global instance", func() {
			SetBuffers(nil)
			pdbg.SetSkips([]string{"globalNo"})
			globalPdbgExcludeTest()
			So(ErrString(), ShouldEqual,
				` [globalPdbgExcludeTest:16] (func.019:167)
   calling no
  [globalPdbgExcludeTest:17] (func.019:167)
    gcalled1
    [globalCNo:26] (globalPdbgExcludeTest:17) (func.019:167)
      gcalled2
`)
		})
	})
}

func failCaller(skip int) (pc uintptr, file string, line int, ok bool) {
	return 0, "fail", skip, false
}
<commit_msg>Fix Expected result for skip test<commit_after>package godbg

import (
	"fmt"
	"os"
	"runtime"
	"testing"
	. "github.com/smartystreets/goconvey/convey"
)

func TestProject(t *testing.T) {
	SkipConvey("Test buffers", t, func() {

		Convey("By Default, equals to std", func() {
			So(Out(), ShouldEqual, os.Stdout)
			So(Err(), ShouldEqual, os.Stderr)
		})
		Convey("When set to buffer, no longer equals to std", func() {
			SetBuffers(nil)
			So(Out(), ShouldNotEqual, os.Stdout)
			So(Err(), ShouldNotEqual, os.Stderr)
		})
		Convey("By Default, a new pdbg instance buffer equals to std", func() {
			apdbg := NewPdbg()
			So(apdbg.Out(), ShouldEqual, os.Stdout)
			So(apdbg.Err(), ShouldEqual, os.Stderr)
		})
		Convey("By Default, a new pdbg instance set to buffer writes no longer equals to std", func() {
			apdbg := NewPdbg(SetBuffers)
			So(apdbg.Out(), ShouldNotEqual, os.Stdout)
			So(apdbg.Err(), ShouldNotEqual, os.Stderr)
		})
		Convey("Test custom buffer on global pdbg", func() {
			pdbg.bout = nil
			pdbg.sout = nil
			pdbg.berr = nil
			pdbg.serr = nil
			fmt.Fprintln(Out(), "test0 content0")
			So(OutString(), ShouldEqual, ``)
			fmt.Fprintln(Err(), "err0 content0")
			So(ErrString(), ShouldEqual, ``)
			SetBuffers(nil)
			fmt.Fprintln(Out(), "test content")
			fmt.Fprintln(Err(), "err1 cerr")
			fmt.Fprintln(Err(), "err2 cerr2")
			fmt.Fprint(Out(), "test2 content2")
			So(OutString(), ShouldEqual, `test content
test2 content2`)
			So(ErrString(), ShouldEqual, `err1 cerr
err2 cerr2
`)
		})

		Convey("Test custom buffer reset on global pdbg", func() {
			SetBuffers(nil)
			fmt.Fprint(Out(), "test content")
			So(OutString(), ShouldEqual, `test content`)
			fmt.Fprint(Err(), "err1 cerr")
			So(ErrString(), ShouldEqual, `err1 cerr`)
			ResetIOs()
			fmt.Fprint(Out(), "test2 content2")
			So(OutString(), ShouldEqual, `test2 content2`)
			fmt.Fprint(Err(), "err2 cerr2")
			So(ErrString(), ShouldEqual, `err2 cerr2`)
		})

		Convey("Test custom buffer on custom pdbg", func() {
			apdbg := NewPdbg(SetBuffers)
			fmt.Fprintln(apdbg.Out(), "test content")
			fmt.Fprintln(apdbg.Err(), "err1 cerr")
			fmt.Fprintln(apdbg.Err(), "err2 cerr2")
			fmt.Fprint(apdbg.Out(), "test2 content2")
			So(apdbg.OutString(), ShouldEqual, `test content
test2 content2`)
			So(apdbg.ErrString(), ShouldEqual, `err1 cerr
err2 cerr2
`)
		})
		Convey("Test custom buffer reset on custom pdbg", func() {
			apdbg := NewPdbg(SetBuffers)
			fmt.Fprint(apdbg.Out(), "test content")
			So(apdbg.OutString(), ShouldEqual, `test content`)
			fmt.Fprint(apdbg.Err(), "err1 cerr")
			So(apdbg.ErrString(), ShouldEqual, `err1 cerr`)
			apdbg.ResetIOs()
			fmt.Fprint(apdbg.Out(), "test2 content2")
			So(apdbg.OutString(), ShouldEqual, `test2 content2`)
			fmt.Fprint(apdbg.Err(), "err2 cerr2")
			So(apdbg.ErrString(), ShouldEqual, `err2 cerr2`)
		})
	})

	SkipConvey("Test pdbg print functions", t, func() {
		Convey("Test pdbg print with global instance", func() {
			SetBuffers(nil)
			Pdbgf("test")
			So(ErrString(), ShouldEqual,
				`[func.012:96]
  test
`)
			ResetIOs()
			prbgtest()
			So(ErrString(), ShouldEqual,
				` [prbgtest:4] (func.012:102)
   prbgtest content
`)
		})

		Convey("Test pdbg print with custom instance", func() {
			apdbg := NewPdbg(SetBuffers)
			apdbg.Pdbgf("test2")
			So(apdbg.ErrString(), ShouldEqual,
				`[func.013:111]
  test2
`)
			apdbg.ResetIOs()
			prbgtestCustom(apdbg)
			So(apdbg.ErrString(), ShouldEqual,
				` [prbgtestCustom:8] (func.013:117)
   prbgtest content2
`)
			apdbg.ResetIOs()
			apdbg.pdbgTestInstance()
			So(apdbg.ErrString(), ShouldEqual,
				` [*Pdbg.pdbgTestInstance:12] (func.013:123)
   pdbgTestInstance content3
`)
		})
		Convey("Test pdbg prints nothing if runtime.Caller fails", func() {
			mycaller = failCaller
			apdbg := NewPdbg(SetBuffers)
			apdbg.Pdbgf("test fail")
			So(apdbg.ErrString(), ShouldEqual, `  test fail
`)
			mycaller = runtime.Caller
		})
	})

	SkipConvey("Test pdbg excludes functions", t, func() {
		Convey("Test pdbg exclude with global instance", func() {
			SetBuffers(nil)
			pdbg.SetExcludes([]string{"globalNo"})
			globalPdbgExcludeTest()
			So(ErrString(), ShouldEqual,
				` [globalPdbgExcludeTest:16] (func.016:143)
   calling no
   [globalCNo:26] (globalPdbgExcludeTest:17) (func.016:143)
     gcalled2
`)
		})
		Convey("Test pdbg exclude with custom instance", func() {
			apdbg := NewPdbg(SetBuffers, OptExcludes([]string{"customNo"}))
			customPdbgExcludeTest(apdbg)
			So(apdbg.ErrString(), ShouldEqual,
				` [customPdbgExcludeTest:30] (func.017:153)
   calling cno
   [customCNo:40] (customPdbgExcludeTest:31) (func.017:153)
     ccalled2
`)
		})
	})

	Convey("Test pdbg skips functions", t, func() {
		Convey("Test pdbg skip with global instance", func() {
			SetBuffers(nil)
			pdbg.SetSkips([]string{"globalNo"})
			globalPdbgExcludeTest()
			So(ErrString(), ShouldEqual,
				`[globalPdbgExcludeTest:16] (func.019:167)
  calling no
  [globalPdbgExcludeTest:17] (func.019:167)
    gcalled1
    [globalCNo:26] (globalPdbgExcludeTest:17) (func.019:167)
      gcalled2
`)
		})
	})
}

func failCaller(skip int) (pc uintptr, file string, line int, ok bool) {
	return 0, "fail", skip, false
}
<|endoftext|>


<commit_before>package gode

import (
	"errors"
	"fmt"
	"io"
	"os"
	"path/filepath"
	"strconv"
	"strings"

	"github.com/dickeyxxx/golock"
	"github.com/franela/goreq"
	"github.com/mitchellh/ioprogress"
	"github.com/ulikunitz/xz"
)

var errInvalidSha = errors.New("Invalid SHA")

// IsSetup returns true if node is setup in RootPath
func IsSetup() (bool, error) {
	exists, err := fileExists(nodeBinPath)
	if !exists {
		return exists, err
	}
	return fileExists(npmBinPath)
}

// Setup downloads and sets up node in the RootPath directory
func Setup() error {
	golock.Lock(lockPath)
	defer golock.Unlock(lockPath)
	if setup, _ := IsSetup(); setup {
		return nil
	}
	if t == nil {
		return errors.New(`node does not offer a prebuilt binary for your OS.
You'll need to compile the tarball from nodejs.org and place the binary at ` + nodeBinPath)
	}
	if err := downloadFile(nodeBinPath, t.URL, t.Sha); err != nil {
		return err
	}
	if err := os.Chmod(nodeBinPath, 0755); err != nil {
		return err
	}
	if err := downloadNpm(); err != nil {
		return err
	}
	if err := os.MkdirAll(modulesDir, 0755); err != nil {
		return err
	}
	return clearOldNodeInstalls()
}

func downloadNpm() error {
	reader, getSha, err := downloadXZ(npmURL)
	if err != nil {
		return err
	}
	tmpDir := tmpDir()

	if err := extractTar(reader, tmpDir); err != nil {
		return err
	}
	if getSha() != npmSha {
		return errInvalidSha
	}
	os.RemoveAll(filepath.Join(npmBasePath))
	os.Rename(filepath.Join(tmpDir, "npm-"+NpmVersion), npmBasePath)
	return os.RemoveAll(tmpDir)
}

func downloadXZ(url string) (io.Reader, func() string, error) {
	req := goreq.Request{Uri: url}
	resp, err := req.Do()
	if err != nil {
		return nil, nil, err
	}
	if err := getHTTPError(resp); err != nil {
		return nil, nil, err
	}
	size, _ := strconv.Atoi(resp.Header.Get("Content-Length"))
	progress := &ioprogress.Reader{
		Reader:   resp.Body,
		Size:     int64(size),
		DrawFunc: ioprogress.DrawTerminalf(os.Stderr, progressDrawFn),
	}
	getSha, reader := computeSha(progress)
	uncompressed, err := xz.NewReader(reader)
	return uncompressed, getSha, nil
}

func downloadFile(path, url, sha string) error {
	reader, getSha, err := downloadXZ(url)
	if err != nil {
		return err
	}
	tmp := filepath.Join(tmpDir(), "file")
	file, err := os.Create(tmp)
	if err != nil {
		return err
	}
	if _, err = io.Copy(file, reader); err != nil {
		return err
	}
	file.Close()
	if getSha() != sha {
		return errInvalidSha
	}
	if err = os.MkdirAll(filepath.Dir(path), 0755); err != nil {
		return err
	}
	os.Remove(path)
	err = os.Rename(tmp, path)
	if err != nil {
		return err
	}
	return os.RemoveAll(filepath.Dir(tmp))
}

func progressDrawFn(progress, total int64) string {
	return fmt.Sprintf("heroku-cli: Adding dependencies... %15s", ioprogress.DrawTextFormatBytes(progress, total))
}

func clearOldNodeInstalls() error {
	for _, name := range getDirsWithPrefix(rootPath, "node-") {
		if !strings.HasPrefix(name, "node-"+NodeVersion) {
			if err := os.RemoveAll(filepath.Join(rootPath, name)); err != nil {
				return err
			}
		}
	}
	for _, name := range getDirsWithPrefix(rootPath, "npm-") {
		if name != "npm-"+NpmVersion {
			if err := os.RemoveAll(filepath.Join(rootPath, name)); err != nil {
				return err
			}
		}
	}
	return nil
}

func getHTTPError(resp *goreq.Response) error {
	if resp.StatusCode < 400 {
		return nil
	}
	var body string
	body = resp.Header.Get("Content-Type")
	return fmt.Errorf("%s: %s", resp.Status, body)
}
<commit_msg>return xz error<commit_after>package gode

import (
	"errors"
	"fmt"
	"io"
	"os"
	"path/filepath"
	"strconv"
	"strings"

	"github.com/dickeyxxx/golock"
	"github.com/franela/goreq"
	"github.com/mitchellh/ioprogress"
	"github.com/ulikunitz/xz"
)

var errInvalidSha = errors.New("Invalid SHA")

// IsSetup returns true if node is setup in RootPath
func IsSetup() (bool, error) {
	exists, err := fileExists(nodeBinPath)
	if !exists {
		return exists, err
	}
	return fileExists(npmBinPath)
}

// Setup downloads and sets up node in the RootPath directory
func Setup() error {
	golock.Lock(lockPath)
	defer golock.Unlock(lockPath)
	if setup, _ := IsSetup(); setup {
		return nil
	}
	if t == nil {
		return errors.New(`node does not offer a prebuilt binary for your OS.
You'll need to compile the tarball from nodejs.org and place the binary at ` + nodeBinPath)
	}
	if err := downloadFile(nodeBinPath, t.URL, t.Sha); err != nil {
		return err
	}
	if err := os.Chmod(nodeBinPath, 0755); err != nil {
		return err
	}
	if err := downloadNpm(); err != nil {
		return err
	}
	if err := os.MkdirAll(modulesDir, 0755); err != nil {
		return err
	}
	return clearOldNodeInstalls()
}

func downloadNpm() error {
	reader, getSha, err := downloadXZ(npmURL)
	if err != nil {
		return err
	}
	tmpDir := tmpDir()

	if err := extractTar(reader, tmpDir); err != nil {
		return err
	}
	if getSha() != npmSha {
		return errInvalidSha
	}
	os.RemoveAll(filepath.Join(npmBasePath))
	os.Rename(filepath.Join(tmpDir, "npm-"+NpmVersion), npmBasePath)
	return os.RemoveAll(tmpDir)
}

func downloadXZ(url string) (io.Reader, func() string, error) {
	req := goreq.Request{Uri: url}
	resp, err := req.Do()
	if err != nil {
		return nil, nil, err
	}
	if err := getHTTPError(resp); err != nil {
		return nil, nil, err
	}
	size, _ := strconv.Atoi(resp.Header.Get("Content-Length"))
	progress := &ioprogress.Reader{
		Reader:   resp.Body,
		Size:     int64(size),
		DrawFunc: ioprogress.DrawTerminalf(os.Stderr, progressDrawFn),
	}
	getSha, reader := computeSha(progress)
	uncompressed, err := xz.NewReader(reader)
	return uncompressed, getSha, err
}

func downloadFile(path, url, sha string) error {
	reader, getSha, err := downloadXZ(url)
	if err != nil {
		return err
	}
	tmp := filepath.Join(tmpDir(), "file")
	file, err := os.Create(tmp)
	if err != nil {
		return err
	}
	if _, err = io.Copy(file, reader); err != nil {
		return err
	}
	file.Close()
	if getSha() != sha {
		return errInvalidSha
	}
	if err = os.MkdirAll(filepath.Dir(path), 0755); err != nil {
		return err
	}
	os.Remove(path)
	err = os.Rename(tmp, path)
	if err != nil {
		return err
	}
	return os.RemoveAll(filepath.Dir(tmp))
}

func progressDrawFn(progress, total int64) string {
	return fmt.Sprintf("heroku-cli: Adding dependencies... %15s", ioprogress.DrawTextFormatBytes(progress, total))
}

func clearOldNodeInstalls() error {
	for _, name := range getDirsWithPrefix(rootPath, "node-") {
		if !strings.HasPrefix(name, "node-"+NodeVersion) {
			if err := os.RemoveAll(filepath.Join(rootPath, name)); err != nil {
				return err
			}
		}
	}
	for _, name := range getDirsWithPrefix(rootPath, "npm-") {
		if name != "npm-"+NpmVersion {
			if err := os.RemoveAll(filepath.Join(rootPath, name)); err != nil {
				return err
			}
		}
	}
	return nil
}

func getHTTPError(resp *goreq.Response) error {
	if resp.StatusCode < 400 {
		return nil
	}
	var body string
	body = resp.Header.Get("Content-Type")
	return fmt.Errorf("%s: %s", resp.Status, body)
}
<|endoftext|>


<commit_before>package gomeh

import (
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"strings"
	"testing"
)

func readKey() string {
	f := "./apikey"
	var key string
	// If API key file exists
	if _, err := os.Stat(f); err == nil {
		// Read API key from file
		fmt.Println("Reading from file.")
		buf, err := ioutil.ReadFile(f)
		if err != nil {
			log.Fatal(err)
		}
		key = string(buf)
	} else {
		fmt.Println("Reading from file.")
		// Read API key from env (for travis)
		key = os.Getenv("meh_apikey")
	}
	// Trim the string to remove any whitespace or linebreaks
	fmt.Println(key)
	return strings.Trim(key, " \n")
}

func ExampleGetMeh_output() {
	apikey := readKey()
	m, err := GetMeh(apikey)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(m)
}

func TestGetMeh(t *testing.T) {
	apikey := readKey()
	m, err := GetMeh(apikey)
	if err != nil {
		t.Error("Failed to retreive data from API.")
	}
	if len(m.Deal.Title) == 0 {
		t.Error("Missing deal.")
	}
}
<commit_msg>travis test fix<commit_after>package gomeh

import (
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"strings"
	"testing"
)

func readKey() string {
	f := "./apikey"
	var key string
	// If API key env exists use that
	if env := os.Getenv("meh_apikey"); env != "" {
		// Read API key from env (for travis)
		key = env
	} else {
		// Read API key from file
		buf, err := ioutil.ReadFile(f)
		if err != nil {
			log.Fatal(err)
		}
		key = string(buf)
	}
	// Trim the string to remove any whitespace or linebreaks
	return strings.Trim(key, " \n")
}

func ExampleGetMeh_output() {
	apikey := readKey()
	m, err := GetMeh(apikey)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(m)
}

func TestGetMeh(t *testing.T) {
	apikey := readKey()
	m, err := GetMeh(apikey)
	if err != nil {
		t.Error("Failed to retreive data from API.")
	}
	if len(m.Deal.Title) == 0 {
		t.Error("Missing deal.")
	}
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"os"
	"path"
	"path/filepath"
	"strings"

	"github.com/disiqueira/gotree"
	"gopkg.in/ini.v1"
)

const (
	configFile = ".gorganizer-{lang}.ini"
)

var cfg *ini.File
var cfgFile string
var language string

func addToTree(folder, file string, tree *gotree.GTStructure) {

	newFile := gotree.GTStructure{Name: file}

	// append to parent, if exists
	for i, item := range tree.Items {
		if item.Name == folder {
			item.Items = append(item.Items, newFile)
			tree.Items[i] = item
			return
		}
	}

	// create parent if missing
	newFolder := gotree.GTStructure{Name: folder}
	newFolder.Items = append(newFolder.Items, newFile)
	tree.Items = append(tree.Items, newFolder)
}

type excludeListType []string

func (e excludeListType) checkExclude(ext string) bool {
	for _, item := range e {
		if item == ext {
			return true
		}
	}
	return false
}

func main() {
	outputFolder := flag.String("output", ".", "Main directory to put organized folders")
	inputFolder := flag.String("directory", ".", "The directory whose files to classify")

	newRule := flag.String("newrule", "", "Insert a new rule. Format ext:folder Example: mp3:Music")
	delRule := flag.String("delrule", "", "Delete a rule. Format ext Example: mp3")

	printRules := flag.Bool("allrules", false, "Print all rules")

	preview := flag.Bool("preview", false, "Only preview, do not move files")

	excludeExtentions := flag.String("exclude", "", "Exclude files will ignore files for organizer. Format pdf,odt")

	flag.StringVar(&language, "language", "en", "Specify language: en|tr|pt")

	flag.Parse()

	initDb()

	defer closeDb()

	var excludeList excludeListType
	excludeList = strings.Split(*excludeExtentions, ",")

	if len(*newRule) > 0 {
		fmt.Println("Creating new rule")
		err := insertRule(*newRule)
		if err != nil {
			fmt.Println(err)
			return
		}
		showRules()
		return
	}

	if len(*delRule) > 0 {
		fmt.Println("Deleting rule")
		deleteRule(*delRule)
		showRules()
		return
	}

	if *printRules {
		showRules()
		return
	}

	files, _ := ioutil.ReadDir(*inputFolder)
	fmt.Println("GOrganizing your Files")

	var tree gotree.GTStructure

	tree.Name = "Files"

	for _, f := range files {
		if f.IsDir() {
			continue
		}

		file := filepath.Join(*inputFolder, f.Name())
		ext := strings.TrimPrefix(path.Ext(file), ".")

		if excludeList.checkExclude(ext) {
			addToTree("Excluded Files", f.Name(), &tree)
			continue
		}

		newFolder := iniGet(ext)

		if len(newFolder) > 0 {

			folder := filepath.Join(*outputFolder, newFolder)
			newFile := filepath.Join(folder, f.Name())

			if !*preview {
				_ = os.Mkdir(folder, os.ModePerm)
				os.Rename(file, newFile)
			}
		} else {
			newFolder = "Unknown extension (will not be moved)"
		}

		addToTree(newFolder, f.Name(), &tree)
	}

	gotree.PrintTree(tree)

	fmt.Println("All files have been gorganized!")
}
<commit_msg>empty ext. is not exclude ext.<commit_after>package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"os"
	"path"
	"path/filepath"
	"strings"

	"github.com/disiqueira/gotree"
	"gopkg.in/ini.v1"
)

const (
	configFile = ".gorganizer-{lang}.ini"
)

var cfg *ini.File
var cfgFile string
var language string

func addToTree(folder, file string, tree *gotree.GTStructure) {

	newFile := gotree.GTStructure{Name: file}

	// append to parent, if exists
	for i, item := range tree.Items {
		if item.Name == folder {
			item.Items = append(item.Items, newFile)
			tree.Items[i] = item
			return
		}
	}

	// create parent if missing
	newFolder := gotree.GTStructure{Name: folder}
	newFolder.Items = append(newFolder.Items, newFile)
	tree.Items = append(tree.Items, newFolder)
}

type excludeListType []string

func (e excludeListType) checkExclude(ext string) bool {
	if ext == "" {
		return false
	}
	for _, item := range e {
		if item == ext {
			return true
		}
	}
	return false
}

func main() {
	outputFolder := flag.String("output", ".", "Main directory to put organized folders")
	inputFolder := flag.String("directory", ".", "The directory whose files to classify")

	newRule := flag.String("newrule", "", "Insert a new rule. Format ext:folder Example: mp3:Music")
	delRule := flag.String("delrule", "", "Delete a rule. Format ext Example: mp3")

	printRules := flag.Bool("allrules", false, "Print all rules")

	preview := flag.Bool("preview", false, "Only preview, do not move files")

	excludeExtentions := flag.String("exclude", "", "Exclude files will ignore files for organizer. Format pdf,odt")

	flag.StringVar(&language, "language", "en", "Specify language: en|tr|pt")

	flag.Parse()

	initDb()

	defer closeDb()

	var excludeList excludeListType
	excludeList = strings.Split(*excludeExtentions, ",")

	if len(*newRule) > 0 {
		fmt.Println("Creating new rule")
		err := insertRule(*newRule)
		if err != nil {
			fmt.Println(err)
			return
		}
		showRules()
		return
	}

	if len(*delRule) > 0 {
		fmt.Println("Deleting rule")
		deleteRule(*delRule)
		showRules()
		return
	}

	if *printRules {
		showRules()
		return
	}

	files, _ := ioutil.ReadDir(*inputFolder)
	fmt.Println("GOrganizing your Files")

	var tree gotree.GTStructure

	tree.Name = "Files"

	for _, f := range files {
		if f.IsDir() {
			continue
		}

		file := filepath.Join(*inputFolder, f.Name())
		ext := strings.TrimPrefix(path.Ext(file), ".")

		if excludeList.checkExclude(ext) {
			addToTree("Excluded Files", f.Name(), &tree)
			continue
		}

		newFolder := iniGet(ext)

		if len(newFolder) > 0 {

			folder := filepath.Join(*outputFolder, newFolder)
			newFile := filepath.Join(folder, f.Name())

			if !*preview {
				_ = os.Mkdir(folder, os.ModePerm)
				os.Rename(file, newFile)
			}
		} else {
			newFolder = "Unknown extension (will not be moved)"
		}

		addToTree(newFolder, f.Name(), &tree)
	}

	gotree.PrintTree(tree)

	fmt.Println("All files have been gorganized!")
}
<|endoftext|>


<commit_before>package gospy_test

import (
	. "github.com/cfmobile/gospy"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	"fmt"
	"errors"
)

const (
	kOriginalStringReturn = "original string value"
	kOriginalIntReturn = 12345
	kOriginalFloatReturn = float64(123.45)
	kOriginalBoolReturn = true
)

var kOriginalErrorReturn = errors.New("some error")

var _ = Describe("GoSpy", func() {
	var subject *GoSpy

	var functionToSpy func(string, int, bool) (string, int, float64, bool, error)
	var panicked bool

	BeforeEach(func() {
	    subject = nil
		panicked = false
		functionToSpy = func(string, int, bool) (string, int, float64, bool, error) {
			return kOriginalStringReturn,
				kOriginalIntReturn,
				kOriginalFloatReturn,
				kOriginalBoolReturn,
				kOriginalErrorReturn
		}
	})

	panicRecover := func() {
		panicked = recover() != nil
	}

	Describe("Constructors", func() {

		var constructorSuccessTests = func() {
			It("should not have panicked", func() {
				Expect(panicked).To(BeFalse())
			})

			It("should have returned a valid *GoSpy object", func() {
				Expect(subject).NotTo(BeNil())
			})
		}

		var constructorFailTests = func() {
			It("should have panicked", func() {
				Expect(panicked).To(BeTrue())
			})

			It("should not have returned a valid *GoSpy object", func() {
				Expect(subject).To(BeNil())
			})
		}

		var spyAndFakeSuccessTests = func() {
			It("should have modified the behaviour of the function to return default type values for each of the return values", func() {
				stringResult, intResult, floatResult, boolResult, errorResult := functionToSpy("something", 10, false)

				Expect(stringResult).To(Equal(""))
				Expect(intResult).To(Equal(0))
				Expect(floatResult).To(Equal(0.0))
				Expect(boolResult).To(Equal(false))
				Expect(errorResult).To(BeNil())
			})
		}

	    Describe("Spy", func() {

	        Context("when calling Spy() with a valid function pointer", func() {
				BeforeEach(func() {
					defer panicRecover()
				    subject = Spy(&functionToSpy)
				})

				constructorSuccessTests()

				It("should not have affected the function's behaviour", func() {
					stringResult, intResult, floatResult, boolResult, errorResult := functionToSpy("something", 10, false)

					Expect(stringResult).To(Equal(kOriginalStringReturn))
					Expect(intResult).To(Equal(kOriginalIntReturn))
					Expect(floatResult).To(Equal(kOriginalFloatReturn))
					Expect(boolResult).To(Equal(kOriginalBoolReturn))
					Expect(errorResult).To(Equal(kOriginalErrorReturn))
				})
	        })

			Context("when calling Spy() with a function var", func() {
			    BeforeEach(func() {
			        defer panicRecover()
					subject = Spy(functionToSpy)
			    })

				constructorFailTests()
			})

			Context("when calling Spy() with any other unexpected type", func() {
			    BeforeEach(func() {
			        defer panicRecover()
					someVar := "some random var"
					subject = Spy(&someVar)
			    })

				constructorFailTests()
			})
	    })

		Describe("SpyAndFake", func() {

			Context("when calling SpyAndFake() with a valid function pointer", func() {
			    BeforeEach(func() {
			        defer panicRecover()
					subject = SpyAndFake(&functionToSpy)
			    })

				constructorSuccessTests()

				spyAndFakeSuccessTests()
			})

			Context("when calling SpyAndFake() with a function object", func() {
				BeforeEach(func() {
				    defer panicRecover()
					subject = SpyAndFake(functionToSpy)
				})

				constructorFailTests()
			})

			Context("when calling SpyAndFake() with any other unexpected type", func() {
			    BeforeEach(func() {
			        defer panicRecover()
					someVar := "some random var"
					subject = SpyAndFake(&someVar)
			    })

				constructorFailTests()
			})
		})

		Describe("SpyAndFakeWithReturn", func() {

			Context("when calling SpyAndFakeWithReturn() with a valid function pointer and valid mock return values", func() {
				mockStringValue := "mock value"
				mockIntValue := 1
				mockFloatValue := 2.0
				mockBoolValue := false
				mockErrorValue := errors.New("mock error")

				BeforeEach(func() {
				    defer panicRecover()
					subject = SpyAndFakeWithReturn(&functionToSpy, mockStringValue, mockIntValue, mockFloatValue, mockBoolValue, mockErrorValue)
				})

				constructorSuccessTests()

				It("should have altered the function to just return the mock values specified", func() {
					stringResult, intResult, floatResult, boolResult, errorResult := functionToSpy("something", 10, false)

					Expect(stringResult).To(Equal(mockStringValue))
					Expect(intResult).To(Equal(mockIntValue))
					Expect(floatResult).To(Equal(mockFloatValue))
					Expect(boolResult).To(Equal(mockBoolValue))
					Expect(errorResult).To(Equal(mockErrorValue))
				})
			})

			Context("when calling SpyAndFakeWithReturn() with no fake return values while the monitored function expects return values", func() {
			    BeforeEach(func() {
			        defer panicRecover()
					subject = SpyAndFakeWithReturn(&functionToSpy)
			    })

				// It should succeed and mock the function to return default type values for each of the return values

				constructorSuccessTests()

				spyAndFakeSuccessTests()
			})

			Context("when calling SpyAndFakeWithReturn() with an invalid first argument (not a function pointer)", func() {
			    BeforeEach(func() {
			        defer panicRecover()
					subject = SpyAndFakeWithReturn(functionToSpy, "mock", 1, 2.0, false, nil)
			    })

				constructorFailTests()
			})

			Context("when calling SpyAndFakeWithReturn() with an incorrect number of arguments (not matching the number of return values in the monitored function)", func() {
			    BeforeEach(func() {
			        defer panicRecover()
					subject = SpyAndFakeWithReturn(&functionToSpy, "mock", 1)
			    })

				constructorFailTests()
			})

			Context("when calling SpyAndFakeWithReturn() with an incorrect variable type for any of the mock return values", func() {
			    BeforeEach(func() {
			        defer panicRecover()
					subject = SpyAndFakeWithReturn(&functionToSpy, 0, 1, 2.0, false, nil)
			    })

				constructorFailTests()
			})
		})
	})

	Context("when a valid GoSpy object is created", func() {
		var expectedCalledState bool
		var expectedCallCount int
		var expectedCallList CallList

		// Definition of common tests for each scenario
		var goSpyResetTests = func() {
			Context("when Reset() is called", func() {
				BeforeEach(func() {
					subject.Reset()
				})

				It("should zero the call count", func() {
					Expect(subject.CallCount()).To(BeZero())
				})

				It("should return a nil call list", func() {
					Expect(subject.Calls()).To(BeNil())
				})

				It("should have reset the call indicator", func() {
					Expect(subject.Called()).To(BeFalse())
				})
			})
		}

		var goSpyRestoreTests = func(existingCallCount int, existingCallList CallList) {
			Context("when Restore() is called", func() {
				BeforeEach(func() {
					subject.Restore()
				})

				It("should not have affected the existing call count", func() {
					Expect(subject.CallCount()).To(Equal(existingCallCount))
				})

				It("should not have affected the call list", func() {
					Expect(subject.Calls()).To(Equal(existingCallList))
				})

				It("should no longer monitor subsequent calls to the function", func() {
					Expect(subject.CallCount()).To(Equal(existingCallCount))

					functionToSpy("another call", 101, true)

					Expect(subject.CallCount()).To(Equal(existingCallCount))
					Expect(subject.Calls()).NotTo(ContainElement(ArgList{"another call", 101, true}))
				})
			})
		}

		var goSpyCalledTest = func(expectedCalledState bool) {
			wasCalled := "was"
			if !expectedCalledState {
				wasCalled = "was not"
			}

			It(fmt.Sprintf("should indicate that the function %s Called()", wasCalled), func() {
				Expect(subject.Called()).To(Equal(expectedCalledState))
			})
		}

		var goSpyCallCountTest = func(expectedCallCount int) {
			It(fmt.Sprintf("should indicate a CallCount() of %d", expectedCallCount), func() {
				Expect(subject.CallCount()).To(Equal(expectedCallCount))
			})
		}

		var goSpyCallsTest = func(expectedCallList CallList) {
			msg := "an expected and ordered"
			if expectedCallList == nil {
				msg = "a nil"
			}

			It(fmt.Sprintf("should contain %s list of Calls()", msg), func() {
			    Expect(subject.Calls()).To(Equal(expectedCallList))
			})
		}

		BeforeEach(func() {
			subject = Spy(&functionToSpy)
		})

		Context("as soon as it's created", func() {
			expectedCalledState = false
		    expectedCallCount = 0
			expectedCallList = nil

			goSpyCalledTest(expectedCalledState)

			goSpyCallCountTest(expectedCallCount)

			goSpyCallsTest(expectedCallList)

			goSpyResetTests()

			goSpyRestoreTests(expectedCallCount, expectedCallList)

			Context("when ArgsForCall() is called with no calls in the Spy", func() {
				BeforeEach(func() {
					defer panicRecover()
					subject.ArgsForCall(0)
				})

				It("should panic", func() {
					Expect(panicked).To(BeTrue())
				})
			})
		})

		Context("and the monitored function is called once", func() {
			expectedCalledState = true
			expectedCallCount = 1
			expectedArgList := ArgList{"test value", 101, true}
			expectedCallList = CallList{expectedArgList}

			BeforeEach(func() {
			    functionToSpy("test value", 101, true)
			})

			goSpyCalledTest(expectedCalledState)

			goSpyCallCountTest(expectedCallCount)

			goSpyCallsTest(expectedCallList)

			goSpyResetTests()

			goSpyRestoreTests(expectedCallCount, expectedCallList)

			It("ArgsForCall() should return the arguments that were used in the call", func() {
			    Expect(subject.ArgsForCall(0)).To(Equal(expectedArgList))
			})
		})

		Context("and the monitored function is called several times", func() {
			expectedCalledState = true
			expectedCallCount = 3
			expectedCallList = CallList{
				{"call 1", 1, true},
				{"call 2", 2, false},
				{"call 3", 3, true},
			}

			BeforeEach(func() {
			    functionToSpy("call 1", 1, true)
				functionToSpy("call 2", 2, false)
				functionToSpy("call 3", 3, true)
			})

			goSpyCalledTest(expectedCalledState)

			goSpyCallCountTest(expectedCallCount)

			goSpyCallsTest(expectedCallList)

			goSpyResetTests()

			goSpyRestoreTests(expectedCallCount, expectedCallList)

			It("ArgsForCall(n) should return the arguments for the n-th call (0-based index) ", func() {
			    Expect(subject.ArgsForCall(0)).To(Equal(expectedCallList[0]))
			    Expect(subject.ArgsForCall(1)).To(Equal(expectedCallList[1]))
			    Expect(subject.ArgsForCall(2)).To(Equal(expectedCallList[2]))
			})
		})
	})
})
<commit_msg>RS - Renamed spyAndFakeSuccessTests() to something more descriptive.<commit_after>package gospy_test

import (
	. "github.com/cfmobile/gospy"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	"fmt"
	"errors"
)

const (
	kOriginalStringReturn = "original string value"
	kOriginalIntReturn = 12345
	kOriginalFloatReturn = float64(123.45)
	kOriginalBoolReturn = true
)

var kOriginalErrorReturn = errors.New("some error")

var _ = Describe("GoSpy", func() {
	var subject *GoSpy

	var functionToSpy func(string, int, bool) (string, int, float64, bool, error)
	var panicked bool

	BeforeEach(func() {
	    subject = nil
		panicked = false
		functionToSpy = func(string, int, bool) (string, int, float64, bool, error) {
			return kOriginalStringReturn,
				kOriginalIntReturn,
				kOriginalFloatReturn,
				kOriginalBoolReturn,
				kOriginalErrorReturn
		}
	})

	panicRecover := func() {
		panicked = recover() != nil
	}

	Describe("Constructors", func() {

		var constructorSuccessTests = func() {
			It("should not have panicked", func() {
				Expect(panicked).To(BeFalse())
			})

			It("should have returned a valid *GoSpy object", func() {
				Expect(subject).NotTo(BeNil())
			})
		}

		var constructorFailTests = func() {
			It("should have panicked", func() {
				Expect(panicked).To(BeTrue())
			})

			It("should not have returned a valid *GoSpy object", func() {
				Expect(subject).To(BeNil())
			})
		}

		var itShouldMakeTheFunctionReturnDefaultValues = func() {
			It("should have modified the behaviour of the function to return default type values for each of the return values", func() {
				stringResult, intResult, floatResult, boolResult, errorResult := functionToSpy("something", 10, false)

				Expect(stringResult).To(Equal(""))
				Expect(intResult).To(Equal(0))
				Expect(floatResult).To(Equal(0.0))
				Expect(boolResult).To(Equal(false))
				Expect(errorResult).To(BeNil())
			})
		}

	    Describe("Spy", func() {

	        Context("when calling Spy() with a valid function pointer", func() {
				BeforeEach(func() {
					defer panicRecover()
				    subject = Spy(&functionToSpy)
				})

				constructorSuccessTests()

				It("should not have affected the function's behaviour", func() {
					stringResult, intResult, floatResult, boolResult, errorResult := functionToSpy("something", 10, false)

					Expect(stringResult).To(Equal(kOriginalStringReturn))
					Expect(intResult).To(Equal(kOriginalIntReturn))
					Expect(floatResult).To(Equal(kOriginalFloatReturn))
					Expect(boolResult).To(Equal(kOriginalBoolReturn))
					Expect(errorResult).To(Equal(kOriginalErrorReturn))
				})
	        })

			Context("when calling Spy() with a function var", func() {
			    BeforeEach(func() {
			        defer panicRecover()
					subject = Spy(functionToSpy)
			    })

				constructorFailTests()
			})

			Context("when calling Spy() with any other unexpected type", func() {
			    BeforeEach(func() {
			        defer panicRecover()
					someVar := "some random var"
					subject = Spy(&someVar)
			    })

				constructorFailTests()
			})
	    })

		Describe("SpyAndFake", func() {

			Context("when calling SpyAndFake() with a valid function pointer", func() {
			    BeforeEach(func() {
			        defer panicRecover()
					subject = SpyAndFake(&functionToSpy)
			    })

				constructorSuccessTests()

				itShouldMakeTheFunctionReturnDefaultValues()
			})

			Context("when calling SpyAndFake() with a function object", func() {
				BeforeEach(func() {
				    defer panicRecover()
					subject = SpyAndFake(functionToSpy)
				})

				constructorFailTests()
			})

			Context("when calling SpyAndFake() with any other unexpected type", func() {
			    BeforeEach(func() {
			        defer panicRecover()
					someVar := "some random var"
					subject = SpyAndFake(&someVar)
			    })

				constructorFailTests()
			})
		})

		Describe("SpyAndFakeWithReturn", func() {

			Context("when calling SpyAndFakeWithReturn() with a valid function pointer and valid mock return values", func() {
				mockStringValue := "mock value"
				mockIntValue := 1
				mockFloatValue := 2.0
				mockBoolValue := false
				mockErrorValue := errors.New("mock error")

				BeforeEach(func() {
				    defer panicRecover()
					subject = SpyAndFakeWithReturn(&functionToSpy, mockStringValue, mockIntValue, mockFloatValue, mockBoolValue, mockErrorValue)
				})

				constructorSuccessTests()

				It("should have altered the function to just return the mock values specified", func() {
					stringResult, intResult, floatResult, boolResult, errorResult := functionToSpy("something", 10, false)

					Expect(stringResult).To(Equal(mockStringValue))
					Expect(intResult).To(Equal(mockIntValue))
					Expect(floatResult).To(Equal(mockFloatValue))
					Expect(boolResult).To(Equal(mockBoolValue))
					Expect(errorResult).To(Equal(mockErrorValue))
				})
			})

			Context("when calling SpyAndFakeWithReturn() with no fake return values while the monitored function expects return values", func() {
			    BeforeEach(func() {
			        defer panicRecover()
					subject = SpyAndFakeWithReturn(&functionToSpy)
			    })

				constructorSuccessTests()

				itShouldMakeTheFunctionReturnDefaultValues()
			})

			Context("when calling SpyAndFakeWithReturn() with an invalid first argument (not a function pointer)", func() {
			    BeforeEach(func() {
			        defer panicRecover()
					subject = SpyAndFakeWithReturn(functionToSpy, "mock", 1, 2.0, false, nil)
			    })

				constructorFailTests()
			})

			Context("when calling SpyAndFakeWithReturn() with an incorrect number of arguments (not matching the number of return values in the monitored function)", func() {
			    BeforeEach(func() {
			        defer panicRecover()
					subject = SpyAndFakeWithReturn(&functionToSpy, "mock", 1)
			    })

				constructorFailTests()
			})

			Context("when calling SpyAndFakeWithReturn() with an incorrect variable type for any of the mock return values", func() {
			    BeforeEach(func() {
			        defer panicRecover()
					subject = SpyAndFakeWithReturn(&functionToSpy, 0, 1, 2.0, false, nil)
			    })

				constructorFailTests()
			})
		})
	})

	Context("when a valid GoSpy object is created", func() {
		var expectedCalledState bool
		var expectedCallCount int
		var expectedCallList CallList

		// Definition of common tests for each scenario
		var goSpyResetTests = func() {
			Context("when Reset() is called", func() {
				BeforeEach(func() {
					subject.Reset()
				})

				It("should zero the call count", func() {
					Expect(subject.CallCount()).To(BeZero())
				})

				It("should return a nil call list", func() {
					Expect(subject.Calls()).To(BeNil())
				})

				It("should have reset the call indicator", func() {
					Expect(subject.Called()).To(BeFalse())
				})
			})
		}

		var goSpyRestoreTests = func(existingCallCount int, existingCallList CallList) {
			Context("when Restore() is called", func() {
				BeforeEach(func() {
					subject.Restore()
				})

				It("should not have affected the existing call count", func() {
					Expect(subject.CallCount()).To(Equal(existingCallCount))
				})

				It("should not have affected the call list", func() {
					Expect(subject.Calls()).To(Equal(existingCallList))
				})

				It("should no longer monitor subsequent calls to the function", func() {
					Expect(subject.CallCount()).To(Equal(existingCallCount))

					functionToSpy("another call", 101, true)

					Expect(subject.CallCount()).To(Equal(existingCallCount))
					Expect(subject.Calls()).NotTo(ContainElement(ArgList{"another call", 101, true}))
				})
			})
		}

		var goSpyCalledTest = func(expectedCalledState bool) {
			wasCalled := "was"
			if !expectedCalledState {
				wasCalled = "was not"
			}

			It(fmt.Sprintf("should indicate that the function %s Called()", wasCalled), func() {
				Expect(subject.Called()).To(Equal(expectedCalledState))
			})
		}

		var goSpyCallCountTest = func(expectedCallCount int) {
			It(fmt.Sprintf("should indicate a CallCount() of %d", expectedCallCount), func() {
				Expect(subject.CallCount()).To(Equal(expectedCallCount))
			})
		}

		var goSpyCallsTest = func(expectedCallList CallList) {
			msg := "an expected and ordered"
			if expectedCallList == nil {
				msg = "a nil"
			}

			It(fmt.Sprintf("should contain %s list of Calls()", msg), func() {
			    Expect(subject.Calls()).To(Equal(expectedCallList))
			})
		}

		BeforeEach(func() {
			subject = Spy(&functionToSpy)
		})

		Context("as soon as it's created", func() {
			expectedCalledState = false
		    expectedCallCount = 0
			expectedCallList = nil

			goSpyCalledTest(expectedCalledState)

			goSpyCallCountTest(expectedCallCount)

			goSpyCallsTest(expectedCallList)

			goSpyResetTests()

			goSpyRestoreTests(expectedCallCount, expectedCallList)

			Context("when ArgsForCall() is called with no calls in the Spy", func() {
				BeforeEach(func() {
					defer panicRecover()
					subject.ArgsForCall(0)
				})

				It("should panic", func() {
					Expect(panicked).To(BeTrue())
				})
			})
		})

		Context("and the monitored function is called once", func() {
			expectedCalledState = true
			expectedCallCount = 1
			expectedArgList := ArgList{"test value", 101, true}
			expectedCallList = CallList{expectedArgList}

			BeforeEach(func() {
			    functionToSpy("test value", 101, true)
			})

			goSpyCalledTest(expectedCalledState)

			goSpyCallCountTest(expectedCallCount)

			goSpyCallsTest(expectedCallList)

			goSpyResetTests()

			goSpyRestoreTests(expectedCallCount, expectedCallList)

			It("ArgsForCall() should return the arguments that were used in the call", func() {
			    Expect(subject.ArgsForCall(0)).To(Equal(expectedArgList))
			})
		})

		Context("and the monitored function is called several times", func() {
			expectedCalledState = true
			expectedCallCount = 3
			expectedCallList = CallList{
				{"call 1", 1, true},
				{"call 2", 2, false},
				{"call 3", 3, true},
			}

			BeforeEach(func() {
			    functionToSpy("call 1", 1, true)
				functionToSpy("call 2", 2, false)
				functionToSpy("call 3", 3, true)
			})

			goSpyCalledTest(expectedCalledState)

			goSpyCallCountTest(expectedCallCount)

			goSpyCallsTest(expectedCallList)

			goSpyResetTests()

			goSpyRestoreTests(expectedCallCount, expectedCallList)

			It("ArgsForCall(n) should return the arguments for the n-th call (0-based index) ", func() {
			    Expect(subject.ArgsForCall(0)).To(Equal(expectedCallList[0]))
			    Expect(subject.ArgsForCall(1)).To(Equal(expectedCallList[1]))
			    Expect(subject.ArgsForCall(2)).To(Equal(expectedCallList[2]))
			})
		})
	})
})
<|endoftext|>


<commit_before>package govcr_test

import (
	"bytes"
	"crypto/tls"
	"fmt"
	"io/ioutil"
	"net/http"
	"testing"

	"net/http/httptest"

	"github.com/seborama/govcr"
)

const (
	wipeCassette = true
	keepCassette = false
)

func TestPlaybackOrder(t *testing.T) {
	cassetteName := "TestPlaybackOrder"
	clientNum := 1

	// create a test server
	ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprintf(w, "Hello, client %d", clientNum)
		clientNum++
	}))

	fmt.Println("Phase 1 ================================================")

	if err := govcr.DeleteCassette(cassetteName, ""); err != nil {
		t.Fatalf("err from govcr.DeleteCassette(): Expected nil, got %s", err)
	}

	vcr := createVCR(cassetteName, wipeCassette)
	client := vcr.Client

	// run requests
	for i := 1; i <= 10; i++ {
		resp, _ := client.Get(ts.URL)

		// check outcome of the request
		checkResponseForTestPlaybackOrder(t, cassetteName, vcr, resp, i, false)

		if !govcr.CassetteExistsAndValid(cassetteName, "") {
			t.Fatalf("CassetteExists: expected true, got false")
		}

		checkStats(t, vcr.Stats(), 0, i, 0)
	}

	fmt.Println("Phase 2 ================================================")
	clientNum = 1

	// re-run request and expect play back from vcr
	vcr = createVCR(cassetteName, keepCassette)
	client = vcr.Client

	// run requests
	for i := 1; i <= 10; i++ {
		resp, _ := client.Get(ts.URL)

		// check outcome of the request
		checkResponseForTestPlaybackOrder(t, cassetteName, vcr, resp, i, false)

		if !govcr.CassetteExistsAndValid(cassetteName, "") {
			t.Fatalf("CassetteExists: expected true, got false")
		}

		checkStats(t, vcr.Stats(), 10, 0, i)
	}
}

func TestNonUtf8EncodableBinaryBody(t *testing.T) {
	cassetteName := "TestNonUtf8EncodableBinaryBody"
	clientNum := 1

	// create a test server
	ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		data := generateBinaryBody(clientNum)
		written, err := w.Write(data)
		if written != len(data) {
			t.Fatalf("** Only %d bytes out of %d were written", written, len(data))
		}
		if err != nil {
			t.Fatalf("err from w.Write(): Expected nil, got %s", err)
		}
		clientNum++
	}))

	fmt.Println("Phase 1 ================================================")

	if err := govcr.DeleteCassette(cassetteName, ""); err != nil {
		t.Fatalf("err from govcr.DeleteCassette(): Expected nil, got %s", err)
	}

	vcr := createVCR(cassetteName, wipeCassette)
	client := vcr.Client

	// run requests
	for i := 1; i <= 10; i++ {
		resp, _ := client.Get(ts.URL)

		// check outcome of the request
		checkResponseForTestPlaybackOrder(t, cassetteName, vcr, resp, i, true)

		if !govcr.CassetteExistsAndValid(cassetteName, "") {
			t.Fatalf("CassetteExists: expected true, got false")
		}

		checkStats(t, vcr.Stats(), 0, i, 0)
	}

	fmt.Println("Phase 2 ================================================")
	clientNum = 1

	// re-run request and expect play back from vcr
	vcr = createVCR(cassetteName, keepCassette)
	client = vcr.Client

	// run requests
	for i := 1; i <= 10; i++ {
		resp, _ := client.Get(ts.URL)

		// check outcome of the request
		checkResponseForTestPlaybackOrder(t, cassetteName, vcr, resp, i, true)

		if !govcr.CassetteExistsAndValid(cassetteName, "") {
			t.Fatalf("CassetteExists: expected true, got false")
		}

		checkStats(t, vcr.Stats(), 10, 0, i)
	}
}

func createVCR(cassetteName string, wipeCassette bool) *govcr.VCRControlPanel {
	// create a custom http.Transport.
	tr := http.DefaultTransport.(*http.Transport)
	tr.TLSClientConfig = &tls.Config{
		InsecureSkipVerify: true, // just an example, not recommended
	}

	// create a vcr
	return govcr.NewVCR(cassetteName,
		&govcr.VCRConfig{
			Client: &http.Client{Transport: tr},
		})
}

func checkResponseForTestPlaybackOrder(t *testing.T, cassetteName string, vcr *govcr.VCRControlPanel, resp *http.Response, i int, binary bool) {
	if resp.StatusCode != http.StatusOK {
		t.Fatalf("resp.StatusCode: Expected %d, got %d", http.StatusOK, resp.StatusCode)
	}

	if resp.Body == nil {
		t.Fatalf("resp.Body: Expected non-nil, got nil")
	}

	bodyData, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		t.Fatalf("err from ioutil.ReadAll(): Expected nil, got %s", err)
	}
	resp.Body.Close()

	if binary {
		expectedBody := generateBinaryBody(i)
		if bytes.Compare(bodyData, expectedBody) != 0 {
			t.Fatalf("Body: expected '%v', got '%v'", expectedBody, bodyData)
		}
	} else {
		expectedBody := fmt.Sprintf("Hello, client %d", i)
		if string(bodyData) != expectedBody {
			t.Fatalf("Body: expected '%s', got '%s'", expectedBody, string(bodyData))
		}
	}
}

func checkStats(t *testing.T, actualStats govcr.Stats, expectedTracksLoaded, expectedTracksRecorded, expectedTrackPlayed int) {
	if actualStats.TracksLoaded != expectedTracksLoaded {
		t.Fatalf("Expected %d track loaded, got %d", expectedTracksLoaded, actualStats.TracksLoaded)
	}

	if actualStats.TracksRecorded != expectedTracksRecorded {
		t.Fatalf("Expected %d track recorded, got %d", expectedTracksRecorded, actualStats.TracksRecorded)
	}

	if actualStats.TracksPlayed != expectedTrackPlayed {
		t.Fatalf("Expected %d track played, got %d", expectedTrackPlayed, actualStats.TracksPlayed)
	}
}

func generateBinaryBody(sequence int) []byte {
	data := make([]byte, 256, 257)
	for i := range data {
		data[i] = byte(i)
	}
	data = append(data, byte(sequence))
	return data
}
<commit_msg>Simplified signature of checkResponseForTestPlaybackOrder<commit_after>package govcr_test

import (
	"bytes"
	"crypto/tls"
	"fmt"
	"io/ioutil"
	"net/http"
	"testing"

	"net/http/httptest"

	"github.com/seborama/govcr"
)

const (
	wipeCassette = true
	keepCassette = false
)

func TestPlaybackOrder(t *testing.T) {
	cassetteName := "TestPlaybackOrder"
	clientNum := 1

	// create a test server
	ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprintf(w, "Hello, client %d", clientNum)
		clientNum++
	}))

	fmt.Println("Phase 1 ================================================")

	if err := govcr.DeleteCassette(cassetteName, ""); err != nil {
		t.Fatalf("err from govcr.DeleteCassette(): Expected nil, got %s", err)
	}

	vcr := createVCR(cassetteName, wipeCassette)
	client := vcr.Client

	// run requests
	for i := 1; i <= 10; i++ {
		resp, _ := client.Get(ts.URL)

		// check outcome of the request
		checkResponseForTestPlaybackOrder(t, resp, i, false)

		if !govcr.CassetteExistsAndValid(cassetteName, "") {
			t.Fatalf("CassetteExists: expected true, got false")
		}

		checkStats(t, vcr.Stats(), 0, i, 0)
	}

	fmt.Println("Phase 2 ================================================")
	clientNum = 1

	// re-run request and expect play back from vcr
	vcr = createVCR(cassetteName, keepCassette)
	client = vcr.Client

	// run requests
	for i := 1; i <= 10; i++ {
		resp, _ := client.Get(ts.URL)

		// check outcome of the request
		checkResponseForTestPlaybackOrder(t, resp, i, false)

		if !govcr.CassetteExistsAndValid(cassetteName, "") {
			t.Fatalf("CassetteExists: expected true, got false")
		}

		checkStats(t, vcr.Stats(), 10, 0, i)
	}
}

func TestNonUtf8EncodableBinaryBody(t *testing.T) {
	cassetteName := "TestNonUtf8EncodableBinaryBody"
	clientNum := 1

	// create a test server
	ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		data := generateBinaryBody(clientNum)
		written, err := w.Write(data)
		if written != len(data) {
			t.Fatalf("** Only %d bytes out of %d were written", written, len(data))
		}
		if err != nil {
			t.Fatalf("err from w.Write(): Expected nil, got %s", err)
		}
		clientNum++
	}))

	fmt.Println("Phase 1 ================================================")

	if err := govcr.DeleteCassette(cassetteName, ""); err != nil {
		t.Fatalf("err from govcr.DeleteCassette(): Expected nil, got %s", err)
	}

	vcr := createVCR(cassetteName, wipeCassette)
	client := vcr.Client

	// run requests
	for i := 1; i <= 10; i++ {
		resp, _ := client.Get(ts.URL)

		// check outcome of the request
		checkResponseForTestPlaybackOrder(t, resp, i, true)

		if !govcr.CassetteExistsAndValid(cassetteName, "") {
			t.Fatalf("CassetteExists: expected true, got false")
		}

		checkStats(t, vcr.Stats(), 0, i, 0)
	}

	fmt.Println("Phase 2 ================================================")
	clientNum = 1

	// re-run request and expect play back from vcr
	vcr = createVCR(cassetteName, keepCassette)
	client = vcr.Client

	// run requests
	for i := 1; i <= 10; i++ {
		resp, _ := client.Get(ts.URL)

		// check outcome of the request
		checkResponseForTestPlaybackOrder(t, resp, i, true)

		if !govcr.CassetteExistsAndValid(cassetteName, "") {
			t.Fatalf("CassetteExists: expected true, got false")
		}

		checkStats(t, vcr.Stats(), 10, 0, i)
	}
}

func createVCR(cassetteName string, wipeCassette bool) *govcr.VCRControlPanel {
	// create a custom http.Transport.
	tr := http.DefaultTransport.(*http.Transport)
	tr.TLSClientConfig = &tls.Config{
		InsecureSkipVerify: true, // just an example, not recommended
	}

	// create a vcr
	return govcr.NewVCR(cassetteName,
		&govcr.VCRConfig{
			Client: &http.Client{Transport: tr},
		})
}

func checkResponseForTestPlaybackOrder(t *testing.T, resp *http.Response, i int, binary bool) {
	if resp.StatusCode != http.StatusOK {
		t.Fatalf("resp.StatusCode: Expected %d, got %d", http.StatusOK, resp.StatusCode)
	}

	if resp.Body == nil {
		t.Fatalf("resp.Body: Expected non-nil, got nil")
	}

	bodyData, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		t.Fatalf("err from ioutil.ReadAll(): Expected nil, got %s", err)
	}
	resp.Body.Close()

	if binary {
		expectedBody := generateBinaryBody(i)
		if bytes.Compare(bodyData, expectedBody) != 0 {
			t.Fatalf("Body: expected '%v', got '%v'", expectedBody, bodyData)
		}
	} else {
		expectedBody := fmt.Sprintf("Hello, client %d", i)
		if string(bodyData) != expectedBody {
			t.Fatalf("Body: expected '%s', got '%s'", expectedBody, string(bodyData))
		}
	}
}

func checkStats(t *testing.T, actualStats govcr.Stats, expectedTracksLoaded, expectedTracksRecorded, expectedTrackPlayed int) {
	if actualStats.TracksLoaded != expectedTracksLoaded {
		t.Fatalf("Expected %d track loaded, got %d", expectedTracksLoaded, actualStats.TracksLoaded)
	}

	if actualStats.TracksRecorded != expectedTracksRecorded {
		t.Fatalf("Expected %d track recorded, got %d", expectedTracksRecorded, actualStats.TracksRecorded)
	}

	if actualStats.TracksPlayed != expectedTrackPlayed {
		t.Fatalf("Expected %d track played, got %d", expectedTrackPlayed, actualStats.TracksPlayed)
	}
}

func generateBinaryBody(sequence int) []byte {
	data := make([]byte, 256, 257)
	for i := range data {
		data[i] = byte(i)
	}
	data = append(data, byte(sequence))
	return data
}
<|endoftext|>