<commit_before>package testflight_test

import (
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"syscall"
	"time"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	"github.com/tedsuo/ifrit"
	"github.com/tedsuo/ifrit/ginkgomon"

	"github.com/concourse/atc/postgresrunner"
	"github.com/concourse/testflight/gitserver"
	"github.com/concourse/testflight/guidserver"
)

var _ = Describe("A job with a git resource", func() {
	var postgresRunner postgresrunner.Runner
	var dbProcess ifrit.Process

	var atcConfigFilePath string

	var atcProcess ifrit.Process

	var (
		gitServer *gitserver.Server

		successGitServer  *gitserver.Server
		failureGitServer  *gitserver.Server
		noUpdateGitServer *gitserver.Server
	)

	BeforeEach(func() {
		var err error

		postgresRunner = postgresrunner.Runner{
			Port: 5433 + GinkgoParallelNode(),
		}

		dbProcess = ifrit.Envoke(postgresRunner)
		postgresRunner.CreateTestDB()

		guidserver.Start(helperRootfs, wardenClient)

		gitServer = gitserver.Start(helperRootfs, wardenClient)
		gitServer.Commit()

		successGitServer = gitserver.Start(helperRootfs, wardenClient)
		failureGitServer = gitserver.Start(helperRootfs, wardenClient)
		noUpdateGitServer = gitserver.Start(helperRootfs, wardenClient)

		atcConfigFile, err := ioutil.TempFile("", "atc-config")
		Ω(err).ShouldNot(HaveOccurred())

		atcConfigFilePath = atcConfigFile.Name()

		_, err = fmt.Fprintf(
			atcConfigFile,
			`---
resources:
  - name: some-git-resource
    type: git
    source:
      uri: %[1]s
      branch: master

  - name: some-git-resource-success
    type: git
    source:
      uri: %[2]s
      branch: success

  - name: some-git-resource-failure
    type: git
    source:
      uri: %[4]s
      branch: failure

  - name: some-git-resource-no-update
    type: git
    source:
      uri: %[3]s
      branch: no-update

jobs:
  - name: some-job
    inputs:
      - resource: some-git-resource
    outputs:
      - resource: some-git-resource-success
        params:
          repository: some-git-resource
    config:
      image: %[5]s
      run:
        path: bash
        args: ["-c", "tail -1 some-git-resource/guids | %[6]s"]

  - name: some-failing-job
    inputs:
      - resource: some-git-resource
    outputs:
      - resource: some-git-resource-no-update
        params:
          repository: some-git-resource
      - resource: some-git-resource-failure
        on: [failure]
        params:
          repository: some-git-resource
    config:
      image: %[5]s
      run:
        path: bash
        args: ["-c", "exit 1"]
`,
			gitServer.URI(),
			successGitServer.URI(),
			failureGitServer.URI(),
			noUpdateGitServer.URI(),
			helperRootfs,
			guidserver.CurlCommand(),
		)
		Ω(err).ShouldNot(HaveOccurred())

		err = atcConfigFile.Close()
		Ω(err).ShouldNot(HaveOccurred())

		atcProcess = ifrit.Envoke(&ginkgomon.Runner{
			Name:          "atc",
			AnsiColorCode: "34m",
			Command: exec.Command(
				builtComponents["atc"],
				"-peerAddr", externalAddr+":8081",
				"-config", atcConfigFilePath,
				"-templates", filepath.Join(atcDir, "server", "templates"),
				"-public", filepath.Join(atcDir, "server", "public"),
				"-sqlDataSource", postgresRunner.DataSourceName(),
				"-checkInterval", "5s",
			),
			StartCheck:        "listening",
			StartCheckTimeout: 5 * time.Second,
		})

		Consistently(atcProcess.Wait(), 1*time.Second).ShouldNot(Receive())
	})

	AfterEach(func() {
		atcProcess.Signal(syscall.SIGINT)
		Eventually(atcProcess.Wait(), 10*time.Second).Should(Receive())

		gitServer.Stop()
		successGitServer.Stop()
		failureGitServer.Stop()
		noUpdateGitServer.Stop()

		guidserver.Stop(wardenClient)

		postgresRunner.DropTestDB()

		dbProcess.Signal(os.Interrupt)
		Eventually(dbProcess.Wait(), 10*time.Second).Should(Receive())

		err := os.Remove(atcConfigFilePath)
		Ω(err).ShouldNot(HaveOccurred())
	})

	It("builds a repo's initial and later commits", func() {
		Eventually(guidserver.ReportingGuids, 5*time.Minute, 10*time.Second).Should(HaveLen(1))
		Ω(guidserver.ReportingGuids()).Should(Equal(gitServer.CommittedGuids()))

		gitServer.Commit()

		Eventually(guidserver.ReportingGuids, 2*time.Minute, 10*time.Second).Should(HaveLen(2))
		Ω(guidserver.ReportingGuids()).Should(Equal(gitServer.CommittedGuids()))
	})

	It("performs success outputs when the build succeeds, and failure outputs when the build fails", func() {
		masterSHA := gitServer.RevParse("master")
		Ω(masterSHA).ShouldNot(BeEmpty())

		// synchronize on the build triggering
		Eventually(guidserver.ReportingGuids, 5*time.Minute, 10*time.Second).Should(HaveLen(1))

		// should have eventually promoted
		Eventually(func() string {
			return successGitServer.RevParse("success")
		}, 10*time.Second, 1*time.Second).Should(Equal(masterSHA))

		// should have promoted to failure branch because of on: [failure]
		Eventually(func() string {
			return failureGitServer.RevParse("failure")
		}, 10*time.Second, 1*time.Second).Should(Equal(masterSHA))

		// should *not* have promoted to no-update branch
		Consistently(func() string {
			return noUpdateGitServer.RevParse("no-update")
		}, 10*time.Second, 1*time.Second).Should(BeEmpty())
	})
})
<commit_msg>change a 3 to a 4 and a 4 to a 3<commit_after>package testflight_test

import (
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"syscall"
	"time"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	"github.com/tedsuo/ifrit"
	"github.com/tedsuo/ifrit/ginkgomon"

	"github.com/concourse/atc/postgresrunner"
	"github.com/concourse/testflight/gitserver"
	"github.com/concourse/testflight/guidserver"
)

var _ = Describe("A job with a git resource", func() {
	var postgresRunner postgresrunner.Runner
	var dbProcess ifrit.Process

	var atcConfigFilePath string

	var atcProcess ifrit.Process

	var (
		gitServer *gitserver.Server

		successGitServer  *gitserver.Server
		failureGitServer  *gitserver.Server
		noUpdateGitServer *gitserver.Server
	)

	BeforeEach(func() {
		var err error

		postgresRunner = postgresrunner.Runner{
			Port: 5433 + GinkgoParallelNode(),
		}

		dbProcess = ifrit.Envoke(postgresRunner)
		postgresRunner.CreateTestDB()

		guidserver.Start(helperRootfs, wardenClient)

		gitServer = gitserver.Start(helperRootfs, wardenClient)
		gitServer.Commit()

		successGitServer = gitserver.Start(helperRootfs, wardenClient)
		failureGitServer = gitserver.Start(helperRootfs, wardenClient)
		noUpdateGitServer = gitserver.Start(helperRootfs, wardenClient)

		atcConfigFile, err := ioutil.TempFile("", "atc-config")
		Ω(err).ShouldNot(HaveOccurred())

		atcConfigFilePath = atcConfigFile.Name()

		_, err = fmt.Fprintf(
			atcConfigFile,
			`---
resources:
  - name: some-git-resource
    type: git
    source:
      uri: %[1]s
      branch: master

  - name: some-git-resource-success
    type: git
    source:
      uri: %[2]s
      branch: success

  - name: some-git-resource-failure
    type: git
    source:
      uri: %[3]s
      branch: failure

  - name: some-git-resource-no-update
    type: git
    source:
      uri: %[4]s
      branch: no-update

jobs:
  - name: some-job
    inputs:
      - resource: some-git-resource
    outputs:
      - resource: some-git-resource-success
        params:
          repository: some-git-resource
    config:
      image: %[5]s
      run:
        path: bash
        args: ["-c", "tail -1 some-git-resource/guids | %[6]s"]

  - name: some-failing-job
    inputs:
      - resource: some-git-resource
    outputs:
      - resource: some-git-resource-no-update
        params:
          repository: some-git-resource
      - resource: some-git-resource-failure
        on: [failure]
        params:
          repository: some-git-resource
    config:
      image: %[5]s
      run:
        path: bash
        args: ["-c", "exit 1"]
`,
			gitServer.URI(),
			successGitServer.URI(),
			failureGitServer.URI(),
			noUpdateGitServer.URI(),
			helperRootfs,
			guidserver.CurlCommand(),
		)
		Ω(err).ShouldNot(HaveOccurred())

		err = atcConfigFile.Close()
		Ω(err).ShouldNot(HaveOccurred())

		atcProcess = ifrit.Envoke(&ginkgomon.Runner{
			Name:          "atc",
			AnsiColorCode: "34m",
			Command: exec.Command(
				builtComponents["atc"],
				"-peerAddr", externalAddr+":8081",
				"-config", atcConfigFilePath,
				"-templates", filepath.Join(atcDir, "server", "templates"),
				"-public", filepath.Join(atcDir, "server", "public"),
				"-sqlDataSource", postgresRunner.DataSourceName(),
				"-checkInterval", "5s",
			),
			StartCheck:        "listening",
			StartCheckTimeout: 5 * time.Second,
		})

		Consistently(atcProcess.Wait(), 1*time.Second).ShouldNot(Receive())
	})

	AfterEach(func() {
		atcProcess.Signal(syscall.SIGINT)
		Eventually(atcProcess.Wait(), 10*time.Second).Should(Receive())

		gitServer.Stop()
		successGitServer.Stop()
		failureGitServer.Stop()
		noUpdateGitServer.Stop()

		guidserver.Stop(wardenClient)

		postgresRunner.DropTestDB()

		dbProcess.Signal(os.Interrupt)
		Eventually(dbProcess.Wait(), 10*time.Second).Should(Receive())

		err := os.Remove(atcConfigFilePath)
		Ω(err).ShouldNot(HaveOccurred())
	})

	It("builds a repo's initial and later commits", func() {
		Eventually(guidserver.ReportingGuids, 5*time.Minute, 10*time.Second).Should(HaveLen(1))
		Ω(guidserver.ReportingGuids()).Should(Equal(gitServer.CommittedGuids()))

		gitServer.Commit()

		Eventually(guidserver.ReportingGuids, 2*time.Minute, 10*time.Second).Should(HaveLen(2))
		Ω(guidserver.ReportingGuids()).Should(Equal(gitServer.CommittedGuids()))
	})

	It("performs success outputs when the build succeeds, and failure outputs when the build fails", func() {
		masterSHA := gitServer.RevParse("master")
		Ω(masterSHA).ShouldNot(BeEmpty())

		// synchronize on the build triggering
		Eventually(guidserver.ReportingGuids, 5*time.Minute, 10*time.Second).Should(HaveLen(1))

		// should have eventually promoted
		Eventually(func() string {
			return successGitServer.RevParse("success")
		}, 10*time.Second, 1*time.Second).Should(Equal(masterSHA))

		// should have promoted to failure branch because of on: [failure]
		Eventually(func() string {
			return failureGitServer.RevParse("failure")
		}, 10*time.Second, 1*time.Second).Should(Equal(masterSHA))

		// should *not* have promoted to no-update branch
		Consistently(func() string {
			return noUpdateGitServer.RevParse("no-update")
		}, 10*time.Second, 1*time.Second).Should(BeEmpty())
	})
})
<|endoftext|>


<commit_before>package game

import (
  "errors"
  "rand"
  "regexp"
  "strings"
  "json"
  "fmt"
  "io"
  "io/ioutil"
)

type Damage struct {
  Piercing int
  Smashing int
  Fire     int
}

type Connect int

const (
  Hit Connect = iota
  Miss
  Dodge
)

type Resolution struct {
  Connect Connect
  Damage  Damage
  Target  *Entity
}

type TargetType int

const (
  NoTarget TargetType = 1 << iota
  EntityTarget
  CellTarget
)

type Target struct {
  Type TargetType
  X, Y int
}

type baseWeapon interface {
  // Cost in AP that the source Entity must spent to use this weapon.
  Cost(source *Entity) int

  // Returns a list of all valid targets.
  ValidTargets(source *Entity) []Target

  // Does any effects for when the player mouses over something while this
  // weapon is selected, such as highlighting the region that would be hit
  // with an AOE attack
  MouseOver(source *Entity, bx, by float64)

  // Returns a Resolution indicating everything that happened in once instance of an attack
  // with this weapon
  Damage(source *Entity, target Target) []Resolution
}

type Weapon interface {
  // Using the weapon is an Action, so it must satisfy the Action interface
  Action

  baseWeapon
}

type WeaponInstance struct {
  Base string
  Name string
  Path string
}

func (wi WeaponInstance) Icon() string {
  return wi.Path
}

type WeaponSpec struct {
  WeaponInstance
  baseWeapon
}

// TODO: IT would be nice to change to using the reflect system, if possible, instead of
// requiring a WeaponMaker
type WeaponMaker func() baseWeapon

// map from WeaponInstance.Base to a WeaponMaker for the underlying type for that weapon
var weapon_registry map[string]WeaponMaker

// map from WeaponInstance.Name to a Weapon interface for that specific weapon
var weapon_specs_registry map[string]Weapon

func init() {
  weapon_registry = make(map[string]WeaponMaker)
  rstring := "\\s*{\\s*\"Instance\"\\s*:\\s*(\\{[^}]*\\})\\s*,\\s*\"Weapon\"\\s*:\\s*({(\\s|\\S)*})\\s*}\\s*$"
  rstring = strings.Replace(rstring, "\\s", "[ \t\r\n\f]", -1)
  rstring = strings.Replace(rstring, "\\S", "[^ \t\r\n\f]", -1)
  weapon_spec_regexp = regexp.MustCompile(rstring)

  weapon_specs_registry = make(map[string]Weapon)
}
func RegisterWeapon(base string, maker WeaponMaker) {
  if _, ok := weapon_registry[base]; ok {
    panic(fmt.Sprintf("Tried to register the weapon '%s' twice.", base))
  }
  weapon_registry[base] = maker
}

var weapon_spec_regexp *regexp.Regexp

func init() {
}

func (w *WeaponSpec) UnmarshalJSON(data []byte) error {
  res := weapon_spec_regexp.FindSubmatch(data)
  if res == nil {
    return errors.New(fmt.Sprintf("Unable to unmarshal the JSON for the MarshalWeapon:\n%s\n", string(data)))
  }
  json.Unmarshal(res[1], &w.WeaponInstance)
  maker, ok := weapon_registry[w.WeaponInstance.Base]
  if !ok {
    return errors.New(fmt.Sprintf("Unable to make a weapon of type '%s'", string(res[1])))
  }
  w.baseWeapon = maker()
  json.Unmarshal(res[2], &w.baseWeapon)
  return nil
}

// Reads a file that contains an array of WeaponSpecs in JSON then adds them to the weapon
// spec registry
func LoadWeaponSpecs(spec io.Reader) error {
  var specs []WeaponSpec
  data, err := ioutil.ReadAll(spec)
  if err != nil {
    return err
  }
  err = json.Unmarshal(data, &specs)
  if err != nil {
    return err
  }
  for i := range specs {
    name := specs[i].WeaponInstance.Name
    if _, ok := weapon_specs_registry[name]; ok {
      return errors.New(fmt.Sprintf("Cannot register the weapon '%s' because a weapon has already been registered with that name.", name))
    }
    weapon_specs_registry[name] = specs[i]
  }
  return nil
}

func MakeWeapon(name string) Weapon {
  weapon, ok := weapon_specs_registry[name]
  if !ok {
    panic(fmt.Sprintf("Can't make the weapon '%s' because the spec wasn't loaded.", name))
  }
  if !ok {
    return nil
  }
  return weapon
}

type NoMouseOverEffect struct{}

func (w NoMouseOverEffect) MouseOver(*Entity, float64, float64) {}

type StaticCost int

func (w StaticCost) Cost(_ *Entity) int {
  return int(w)
}

type EntityRange int

func (r EntityRange) ValidTargets(source *Entity) []Target {
  return entitiesWithinRange(source, int(r))
}

type CellRange int

func (r CellRange) ValidTargets(source *Entity) []Target {
  return cellsWithinRange(source, int(r))
}

func entitiesWithinRange(source *Entity, rnge int) []Target {
  x := int(source.pos.X)
  y := int(source.pos.Y)
  var ret []Target
  for _, target := range source.level.Entities {
    x2 := int(target.pos.X)
    y2 := int(target.pos.Y)

    // Don't let units attack something they don't have LOS to
    if _, ok := source.visible[source.level.toVertex(x2, y2)]; !ok {
      continue
    }

    // Don't let units attack something on their own side
    if source.side == target.side {
      continue
    }

    // The obvious check - must not be further away than our weapon's range
    dist := maxNormi(x, y, x2, y2)
    if rnge < dist {
      continue
    }

    // If it passed all of the above tests then we can include it as a valid
    // target
    ret = append(ret, Target{EntityTarget, x2, y2})
  }
  return ret
}

func cellsWithinRange(source *Entity, rnge int) []Target {
  x := int(source.pos.X)
  y := int(source.pos.Y)
  minx := x - rnge
  if minx < 0 {
    minx = 0
  }
  miny := y - rnge
  if miny < 0 {
    miny = 0
  }
  maxx := x + rnge
  if maxx >= len(source.level.grid) {
    maxx = len(source.level.grid)
  }
  maxy := y + rnge
  if maxy >= len(source.level.grid[0]) {
    maxy = len(source.level.grid[0])
  }

  var ret []Target
  for x2 := minx; x2 <= maxx; x2++ {
    for y2 := miny; y2 <= maxy; y2++ {
      // Don't let units attack something they don't have LOS to
      if _, ok := source.visible[source.level.toVertex(x2, y2)]; !ok {
        continue
      }

      // The obvious check - must not be further away than our weapon's range
      dist := maxNormi(x, y, x2, y2)
      if rnge < dist {
        continue
      }

      // If it passed all of the above tests then we can include it as a valid
      // target
      ret = append(ret, Target{CellTarget, x2, y2})
    }
  }
  return ret
}

func init() {
  RegisterWeapon("Club", func() baseWeapon { return &Club{} })
}

type Club struct {
  StaticCost
  EntityRange
  Factor int
  NoMouseOverEffect
}

func (c *Club) Damage(source *Entity, t Target) (res []Resolution) {
  res = []Resolution{Resolution{}}
  r := &res[0]

  var target *Entity
  for _, ent := range source.level.Entities {
    if int(ent.pos.X) != t.X {
      continue
    }
    if int(ent.pos.Y) != t.Y {
      continue
    }
    target = ent
  }
  if target == nil {
    panic("Tried to attack a entity in a cell where there is no entity.")
  }
  r.Target = target

  mod := rand.Intn(10)
  if c.Factor*source.Base.Attack+mod > target.Base.Defense {
    amt := c.Factor*source.Base.Attack + mod - target.Base.Defense - 2
    if amt <= 0 {
      r.Connect = Dodge
      return
    } else {
      r.Connect = Hit
      r.Damage = Damage{Piercing: amt}
    }
  }
  r.Connect = Miss
  return
}

func init() {
  RegisterWeapon("Gun", func() baseWeapon { return &Gun{} })
}

type Gun struct {
  StaticCost
  EntityRange
  Power int
  NoMouseOverEffect
}

func (g *Gun) Damage(source *Entity, t Target) (res []Resolution) {
  // TODO: Extracting the target entity from a Target object should be
  // automatic
  res = []Resolution{Resolution{}}
  r := &res[0]

  var target *Entity
  for _, ent := range source.level.Entities {
    if int(ent.pos.X) != t.X {
      continue
    }
    if int(ent.pos.Y) != t.Y {
      continue
    }
    target = ent
  }
  if target == nil {
    panic("Tried to attack a entity in a cell where there is no entity.")
  }
  r.Target = target

  dist := maxNormi(int(source.pos.X), int(source.pos.Y), int(target.pos.X), int(target.pos.Y))
  acc := 2*int(g.EntityRange) - dist
  if rand.Intn(acc) < dist {
    r.Connect = Miss
    return
  }

  if rand.Intn(target.Base.Defense)/2 > source.Base.Attack {
    r.Connect = Dodge
    return
  }

  r.Connect = Hit
  r.Damage = Damage{Piercing: g.Power}
  return
}

func init() {
  RegisterWeapon("StandardAOE", func() baseWeapon { return &StandardAOE{} })
}

type StandardAOE struct {
  StaticCost
  CellRange
  Power int
  Size  int
}

func (g *StandardAOE) affected(source *Entity, bx, by float64) [][2]int {
  var cx, cy int
  if g.Size%2 == 0 {
    cx = int(bx - 0.5)
    cy = int(by - 0.5)
  } else {
    cx = int(bx)
    cy = int(by)
  }
  var minx, miny, maxx, maxy int
  minx = cx - (g.Size-1)/2
  if minx < 0 {
    minx = 0
  }
  miny = cy - (g.Size-1)/2
  if miny < 0 {
    miny = 0
  }
  maxx = cx + g.Size/2
  if maxx >= len(source.level.grid) {
    maxx = len(source.level.grid)
  }
  maxy = cy + g.Size/2
  if maxy >= len(source.level.grid[0]) {
    maxy = len(source.level.grid[0])
  }

  var ret [][2]int
  for x := minx; x <= maxx; x++ {
    for y := miny; y <= maxy; y++ {
      // TODO: Remove things that can't be hit?  Maybe impassable terrain?
      ret = append(ret, [2]int{x, y})
    }
  }
  return ret
}
func (g *StandardAOE) MouseOver(source *Entity, bx, by float64) {
  targets := g.ValidTargets(source)
  for _, target := range targets {
    if target.Type == CellTarget && target.X == int(bx) && target.Y == int(by) {
      affected := g.affected(source, bx, by)
      for _, pos := range affected {
        source.level.grid[pos[0]][pos[1]].highlight |= AttackMouseOver
      }
      return
    }
  }
}
func (g *StandardAOE) Damage(source *Entity, target Target) (res []Resolution) {
  // TODO: We're about to do a double loop over entities and positions,
  // seems a bit wasteful, lets use a map or something not-stupid
  cells := g.affected(source, float64(target.X), float64(target.Y))
  for _, ent := range source.level.Entities {
    for _, cell := range cells {
      if int(ent.pos.X) != cell[0] {
        continue
      }
      if int(ent.pos.Y) != cell[1] {
        continue
      }
      res = append(res, Resolution{
        Connect: Hit,
        Damage:  Damage{Piercing: g.Power},
        Target:  ent,
      })
      break
    }
  }
  return
}
<commit_msg>Fixed a array-bounds bug in aoe weapons<commit_after>package game

import (
  "errors"
  "rand"
  "regexp"
  "strings"
  "json"
  "fmt"
  "io"
  "io/ioutil"
)

type Damage struct {
  Piercing int
  Smashing int
  Fire     int
}

type Connect int

const (
  Hit Connect = iota
  Miss
  Dodge
)

type Resolution struct {
  Connect Connect
  Damage  Damage
  Target  *Entity
}

type TargetType int

const (
  NoTarget TargetType = 1 << iota
  EntityTarget
  CellTarget
)

type Target struct {
  Type TargetType
  X, Y int
}

type baseWeapon interface {
  // Cost in AP that the source Entity must spent to use this weapon.
  Cost(source *Entity) int

  // Returns a list of all valid targets.
  ValidTargets(source *Entity) []Target

  // Does any effects for when the player mouses over something while this
  // weapon is selected, such as highlighting the region that would be hit
  // with an AOE attack
  MouseOver(source *Entity, bx, by float64)

  // Returns a Resolution indicating everything that happened in once instance of an attack
  // with this weapon
  Damage(source *Entity, target Target) []Resolution
}

type Weapon interface {
  // Using the weapon is an Action, so it must satisfy the Action interface
  Action

  baseWeapon
}

type WeaponInstance struct {
  Base string
  Name string
  Path string
}

func (wi WeaponInstance) Icon() string {
  return wi.Path
}

type WeaponSpec struct {
  WeaponInstance
  baseWeapon
}

// TODO: IT would be nice to change to using the reflect system, if possible, instead of
// requiring a WeaponMaker
type WeaponMaker func() baseWeapon

// map from WeaponInstance.Base to a WeaponMaker for the underlying type for that weapon
var weapon_registry map[string]WeaponMaker

// map from WeaponInstance.Name to a Weapon interface for that specific weapon
var weapon_specs_registry map[string]Weapon

func init() {
  weapon_registry = make(map[string]WeaponMaker)
  rstring := "\\s*{\\s*\"Instance\"\\s*:\\s*(\\{[^}]*\\})\\s*,\\s*\"Weapon\"\\s*:\\s*({(\\s|\\S)*})\\s*}\\s*$"
  rstring = strings.Replace(rstring, "\\s", "[ \t\r\n\f]", -1)
  rstring = strings.Replace(rstring, "\\S", "[^ \t\r\n\f]", -1)
  weapon_spec_regexp = regexp.MustCompile(rstring)

  weapon_specs_registry = make(map[string]Weapon)
}
func RegisterWeapon(base string, maker WeaponMaker) {
  if _, ok := weapon_registry[base]; ok {
    panic(fmt.Sprintf("Tried to register the weapon '%s' twice.", base))
  }
  weapon_registry[base] = maker
}

var weapon_spec_regexp *regexp.Regexp

func init() {
}

func (w *WeaponSpec) UnmarshalJSON(data []byte) error {
  res := weapon_spec_regexp.FindSubmatch(data)
  if res == nil {
    return errors.New(fmt.Sprintf("Unable to unmarshal the JSON for the MarshalWeapon:\n%s\n", string(data)))
  }
  json.Unmarshal(res[1], &w.WeaponInstance)
  maker, ok := weapon_registry[w.WeaponInstance.Base]
  if !ok {
    return errors.New(fmt.Sprintf("Unable to make a weapon of type '%s'", string(res[1])))
  }
  w.baseWeapon = maker()
  json.Unmarshal(res[2], &w.baseWeapon)
  return nil
}

// Reads a file that contains an array of WeaponSpecs in JSON then adds them to the weapon
// spec registry
func LoadWeaponSpecs(spec io.Reader) error {
  var specs []WeaponSpec
  data, err := ioutil.ReadAll(spec)
  if err != nil {
    return err
  }
  err = json.Unmarshal(data, &specs)
  if err != nil {
    return err
  }
  for i := range specs {
    name := specs[i].WeaponInstance.Name
    if _, ok := weapon_specs_registry[name]; ok {
      return errors.New(fmt.Sprintf("Cannot register the weapon '%s' because a weapon has already been registered with that name.", name))
    }
    weapon_specs_registry[name] = specs[i]
  }
  return nil
}

func MakeWeapon(name string) Weapon {
  weapon, ok := weapon_specs_registry[name]
  if !ok {
    panic(fmt.Sprintf("Can't make the weapon '%s' because the spec wasn't loaded.", name))
  }
  if !ok {
    return nil
  }
  return weapon
}

type NoMouseOverEffect struct{}

func (w NoMouseOverEffect) MouseOver(*Entity, float64, float64) {}

type StaticCost int

func (w StaticCost) Cost(_ *Entity) int {
  return int(w)
}

type EntityRange int

func (r EntityRange) ValidTargets(source *Entity) []Target {
  return entitiesWithinRange(source, int(r))
}

type CellRange int

func (r CellRange) ValidTargets(source *Entity) []Target {
  return cellsWithinRange(source, int(r))
}

func entitiesWithinRange(source *Entity, rnge int) []Target {
  x := int(source.pos.X)
  y := int(source.pos.Y)
  var ret []Target
  for _, target := range source.level.Entities {
    x2 := int(target.pos.X)
    y2 := int(target.pos.Y)

    // Don't let units attack something they don't have LOS to
    if _, ok := source.visible[source.level.toVertex(x2, y2)]; !ok {
      continue
    }

    // Don't let units attack something on their own side
    if source.side == target.side {
      continue
    }

    // The obvious check - must not be further away than our weapon's range
    dist := maxNormi(x, y, x2, y2)
    if rnge < dist {
      continue
    }

    // If it passed all of the above tests then we can include it as a valid
    // target
    ret = append(ret, Target{EntityTarget, x2, y2})
  }
  return ret
}

func cellsWithinRange(source *Entity, rnge int) []Target {
  x := int(source.pos.X)
  y := int(source.pos.Y)
  minx := x - rnge
  if minx < 0 {
    minx = 0
  }
  miny := y - rnge
  if miny < 0 {
    miny = 0
  }
  maxx := x + rnge
  if maxx >= len(source.level.grid) - 1 {
    maxx = len(source.level.grid) - 1
  }
  maxy := y + rnge
  if maxy >= len(source.level.grid[0]) - 1 {
    maxy = len(source.level.grid[0]) - 1
  }

  var ret []Target
  for x2 := minx; x2 <= maxx; x2++ {
    for y2 := miny; y2 <= maxy; y2++ {
      // Don't let units attack something they don't have LOS to
      if _, ok := source.visible[source.level.toVertex(x2, y2)]; !ok {
        continue
      }

      // The obvious check - must not be further away than our weapon's range
      dist := maxNormi(x, y, x2, y2)
      if rnge < dist {
        continue
      }

      // If it passed all of the above tests then we can include it as a valid
      // target
      ret = append(ret, Target{CellTarget, x2, y2})
    }
  }
  return ret
}

func init() {
  RegisterWeapon("Club", func() baseWeapon { return &Club{} })
}

type Club struct {
  StaticCost
  EntityRange
  Factor int
  NoMouseOverEffect
}

func (c *Club) Damage(source *Entity, t Target) (res []Resolution) {
  res = []Resolution{Resolution{}}
  r := &res[0]

  var target *Entity
  for _, ent := range source.level.Entities {
    if int(ent.pos.X) != t.X {
      continue
    }
    if int(ent.pos.Y) != t.Y {
      continue
    }
    target = ent
  }
  if target == nil {
    panic("Tried to attack a entity in a cell where there is no entity.")
  }
  r.Target = target

  mod := rand.Intn(10)
  if c.Factor*source.Base.Attack+mod > target.Base.Defense {
    amt := c.Factor*source.Base.Attack + mod - target.Base.Defense - 2
    if amt <= 0 {
      r.Connect = Dodge
      return
    } else {
      r.Connect = Hit
      r.Damage = Damage{Piercing: amt}
    }
  }
  r.Connect = Miss
  return
}

func init() {
  RegisterWeapon("Gun", func() baseWeapon { return &Gun{} })
}

type Gun struct {
  StaticCost
  EntityRange
  Power int
  NoMouseOverEffect
}

func (g *Gun) Damage(source *Entity, t Target) (res []Resolution) {
  // TODO: Extracting the target entity from a Target object should be
  // automatic
  res = []Resolution{Resolution{}}
  r := &res[0]

  var target *Entity
  for _, ent := range source.level.Entities {
    if int(ent.pos.X) != t.X {
      continue
    }
    if int(ent.pos.Y) != t.Y {
      continue
    }
    target = ent
  }
  if target == nil {
    panic("Tried to attack a entity in a cell where there is no entity.")
  }
  r.Target = target

  dist := maxNormi(int(source.pos.X), int(source.pos.Y), int(target.pos.X), int(target.pos.Y))
  acc := 2*int(g.EntityRange) - dist
  if rand.Intn(acc) < dist {
    r.Connect = Miss
    return
  }

  if rand.Intn(target.Base.Defense)/2 > source.Base.Attack {
    r.Connect = Dodge
    return
  }

  r.Connect = Hit
  r.Damage = Damage{Piercing: g.Power}
  return
}

func init() {
  RegisterWeapon("StandardAOE", func() baseWeapon { return &StandardAOE{} })
}

type StandardAOE struct {
  StaticCost
  CellRange
  Power int
  Size  int
}

func (g *StandardAOE) affected(source *Entity, bx, by float64) [][2]int {
  var cx, cy int
  if g.Size%2 == 0 {
    cx = int(bx - 0.5)
    cy = int(by - 0.5)
  } else {
    cx = int(bx)
    cy = int(by)
  }
  var minx, miny, maxx, maxy int
  minx = cx - (g.Size-1)/2
  if minx < 0 {
    minx = 0
  }
  miny = cy - (g.Size-1)/2
  if miny < 0 {
    miny = 0
  }
  maxx = cx + g.Size/2
  if maxx >= len(source.level.grid) - 1{
    maxx = len(source.level.grid) - 1
  }
  maxy = cy + g.Size/2
  if maxy >= len(source.level.grid[0]) - 1 {
    maxy = len(source.level.grid[0]) - 1
  }

  var ret [][2]int
  for x := minx; x <= maxx; x++ {
    for y := miny; y <= maxy; y++ {
      // TODO: Remove things that can't be hit?  Maybe impassable terrain?
      ret = append(ret, [2]int{x, y})
    }
  }
  return ret
}
func (g *StandardAOE) MouseOver(source *Entity, bx, by float64) {
  targets := g.ValidTargets(source)
  for _, target := range targets {
    if target.Type == CellTarget && target.X == int(bx) && target.Y == int(by) {
      affected := g.affected(source, bx, by)
      for _, pos := range affected {
        source.level.grid[pos[0]][pos[1]].highlight |= AttackMouseOver
      }
      return
    }
  }
}
func (g *StandardAOE) Damage(source *Entity, target Target) (res []Resolution) {
  // TODO: We're about to do a double loop over entities and positions,
  // seems a bit wasteful, lets use a map or something not-stupid
  cells := g.affected(source, float64(target.X), float64(target.Y))
  for _, ent := range source.level.Entities {
    for _, cell := range cells {
      if int(ent.pos.X) != cell[0] {
        continue
      }
      if int(ent.pos.Y) != cell[1] {
        continue
      }
      res = append(res, Resolution{
        Connect: Hit,
        Damage:  Damage{Piercing: g.Power},
        Target:  ent,
      })
      break
    }
  }
  return
}
<|endoftext|>


<commit_before>package main

import (
	"time"

	"github.com/joek/picoborgrev"
	"gobot.io/x/gobot"
	"gobot.io/x/gobot/platforms/raspi"
)

func main() {
	gbot := gobot.NewGobot()

	r := raspi.NewRaspiAdaptor("raspi")
	rev := picoborgrev.NewDriver(r, "rev", 10)

	work := func() {
		rev.SetMotorA(0.3)
		time.Sleep(10 * time.Second)
		rev.SetMotorA(-0.3)
		time.Sleep(10 * time.Second)
		rev.SetMotorA(0)
	}

	robot := gobot.NewRobot("beerbot",
		[]gobot.Connection{r},
		[]gobot.Device{rev},
		work,
	)

	gbot.AddRobot(robot)

	gbot.Start()
}
<commit_msg>Fixed example<commit_after>package main

import (
	"time"

	"github.com/joek/picoborgrev"
	"gobot.io/x/gobot"
	"gobot.io/x/gobot/platforms/raspi"
)

func main() {
	r := raspi.NewAdaptor()
	rev := picoborgrev.NewDriver(r, "rev", 10)

	work := func() {
		rev.SetMotorA(0.3)
		time.Sleep(10 * time.Second)
		rev.SetMotorA(-0.3)
		time.Sleep(10 * time.Second)
		rev.SetMotorA(0)
	}

	robot := gobot.NewRobot("beerbot",
		[]gobot.Connection{r},
		[]gobot.Device{rev},
		work,
	)

	robot.Start()
}
<|endoftext|>


<commit_before>// +build linux

package linux

import (
	"os/exec"
	"strings"

	"github.com/mackerelio/mackerel-agent/logging"
	"github.com/shirou/gopsutil/host"
)

// KernelGenerator XXX
type KernelGenerator struct {
}

// Key XXX
func (g *KernelGenerator) Key() string {
	return "kernel"
}

var kernelLogger = logging.GetLogger("spec.kernel")

// Generate XXX
func (g *KernelGenerator) Generate() (interface{}, error) {
	commands := map[string][]string{
		"name":    {"uname", "-s"},
		"release": {"uname", "-r"},
		"version": {"uname", "-v"},
		"machine": {"uname", "-m"},
		"os":      {"uname", "-o"},
	}

	results := make(map[string]string)
	for key, command := range commands {
		out, err := exec.Command(command[0], command[1]).Output()
		if err != nil {
			kernelLogger.Errorf("Failed to run %s %s (skip this spec): %s", command[0], command[1], err)
			return nil, err
		}
		str := strings.TrimSpace(string(out))

		results[key] = str
	}

	hostInfo, err := host.Info()
	if err != nil {
		kernelLogger.Errorf("Failed to get platform information: %s", err)
	}

	if np := normalizePlatform(hostInfo.Platform); np != "" {
		platformInfo := np + " " + hostInfo.PlatformVersion

		// when platform version is empty string
		platformInfo = strings.TrimSpace(platformInfo)

		results["platform"] = platformInfo
	}

	return results, nil
}

func normalizePlatform(platform string) string {
	var normalized string

	switch platform {
	case "debian":
		normalized = "Debian"
	case "ubuntu":
		normalized = "Ubuntu"
	case "linuxmint":
		normalized = "Linux Mint"
	case "raspbian":
		normalized = "Raspbian"
	case "fedora":
		normalized = "Fedora"
	case "oracle":
		normalized = "Oracle Linux"
	case "centos":
		normalized = "CentOS"
	case "redhat":
		normalized = "Red Hat Enterprise Linux"
	case "scientific":
		normalized = "Scientific Linux"
	case "amazon":
		normalized = "Amazon Linux"
	case "xenserver":
		normalized = "XenServer"
	case "cloudlinux":
		normalized = "CloudLinux"
	case "ibm_powerkvm":
		normalized = "IBM PowerKVM"
	case "suse":
		normalized = "SUSE Linux Enterprise Server"
	case "opensuse":
		normalized = "openSUSE"
	case "gentoo":
		normalized = "Gentoo Linux"
	case "slackware":
		normalized = "Slackware"
	case "arch":
		normalized = "Arch Linux"
	case "exherbo":
		normalized = "Exherbo"
	case "alpine":
		normalized = "Alpine Linux"
	case "coreos":
		normalized = "CoreOS"
	default:
		normalized = ""
	}

	return normalized
}
<commit_msg>Add check for Oracle Enterprise Linux<commit_after>// +build linux

package linux

import (
	"os/exec"
	"strings"

	"github.com/mackerelio/mackerel-agent/logging"
	"github.com/shirou/gopsutil/host"
)

// KernelGenerator XXX
type KernelGenerator struct {
}

// Key XXX
func (g *KernelGenerator) Key() string {
	return "kernel"
}

var kernelLogger = logging.GetLogger("spec.kernel")

// Generate XXX
func (g *KernelGenerator) Generate() (interface{}, error) {
	commands := map[string][]string{
		"name":    {"uname", "-s"},
		"release": {"uname", "-r"},
		"version": {"uname", "-v"},
		"machine": {"uname", "-m"},
		"os":      {"uname", "-o"},
	}

	results := make(map[string]string)
	for key, command := range commands {
		out, err := exec.Command(command[0], command[1]).Output()
		if err != nil {
			kernelLogger.Errorf("Failed to run %s %s (skip this spec): %s", command[0], command[1], err)
			return nil, err
		}
		str := strings.TrimSpace(string(out))

		results[key] = str
	}

	hostInfo, err := host.Info()
	if err != nil {
		kernelLogger.Errorf("Failed to get platform information: %s", err)
	}

	if np := normalizePlatform(hostInfo.Platform); np != "" {
		platformInfo := np + " " + hostInfo.PlatformVersion

		// when platform version is empty string
		platformInfo = strings.TrimSpace(platformInfo)

		results["platform"] = platformInfo
	}

	return results, nil
}

func normalizePlatform(platform string) string {
	var normalized string

	switch platform {
	case "debian":
		normalized = "Debian"
	case "ubuntu":
		normalized = "Ubuntu"
	case "linuxmint":
		normalized = "Linux Mint"
	case "raspbian":
		normalized = "Raspbian"
	case "fedora":
		normalized = "Fedora"
	case "oracle":
		normalized = "Oracle Linux"
	case "enterpriseenterprise":
		normalized = "Oracle Enterprise Linux"
	case "centos":
		normalized = "CentOS"
	case "redhat":
		normalized = "Red Hat Enterprise Linux"
	case "scientific":
		normalized = "Scientific Linux"
	case "amazon":
		normalized = "Amazon Linux"
	case "xenserver":
		normalized = "XenServer"
	case "cloudlinux":
		normalized = "CloudLinux"
	case "ibm_powerkvm":
		normalized = "IBM PowerKVM"
	case "suse":
		normalized = "SUSE Linux Enterprise Server"
	case "opensuse":
		normalized = "openSUSE"
	case "gentoo":
		normalized = "Gentoo Linux"
	case "slackware":
		normalized = "Slackware"
	case "arch":
		normalized = "Arch Linux"
	case "exherbo":
		normalized = "Exherbo"
	case "alpine":
		normalized = "Alpine Linux"
	case "coreos":
		normalized = "CoreOS"
	default:
		normalized = ""
	}

	return normalized
}
<|endoftext|>


<commit_before>// +build linux

package linux

import (
	"bufio"
	"os"
	"regexp"

	"github.com/mackerelio/golib/logging"
)

var memItems = map[string]*regexp.Regexp{
	"total":            regexp.MustCompile(`^MemTotal:\s+(\d+) (.+)$`),
	"free":             regexp.MustCompile(`^MemFree:\s+(\d+) (.+)$`),
	"buffers":          regexp.MustCompile(`^Buffers:\s+(\d+) (.+)$`),
	"cached":           regexp.MustCompile(`^Cached:\s+(\d+) (.+)$`),
	"active":           regexp.MustCompile(`^Active:\s+(\d+) (.+)$`),
	"inactive":         regexp.MustCompile(`^Inactive:\s+(\d+) (.+)$`),
	"high_total":       regexp.MustCompile(`^HighTotal:\s+(\d+) (.+)$`),
	"high_free":        regexp.MustCompile(`^HighFree:\s+(\d+) (.+)$`),
	"low_total":        regexp.MustCompile(`^LowTotal:\s+(\d+) (.+)$`),
	"low_free":         regexp.MustCompile(`^LowFree:\s+(\d+) (.+)$`),
	"dirty":            regexp.MustCompile(`^Dirty:\s+(\d+) (.+)$`),
	"writeback":        regexp.MustCompile(`^Writeback:\s+(\d+) (.+)$`),
	"anon_pages":       regexp.MustCompile(`^AnonPages:\s+(\d+) (.+)$`),
	"mapped":           regexp.MustCompile(`^Mapped:\s+(\d+) (.+)$`),
	"slab":             regexp.MustCompile(`^Slab:\s+(\d+) (.+)$`),
	"slab_reclaimable": regexp.MustCompile(`^SReclaimable:\s+(\d+) (.+)$`),
	"slab_unreclaim":   regexp.MustCompile(`^SUnreclaim:\s+(\d+) (.+)$`),
	"page_tables":      regexp.MustCompile(`^PageTables:\s+(\d+) (.+)$`),
	"nfs_unstable":     regexp.MustCompile(`^NFS_Unstable:\s+(\d+) (.+)$`),
	"bounce":           regexp.MustCompile(`^Bounce:\s+(\d+) (.+)$`),
	"commit_limit":     regexp.MustCompile(`^CommitLimit:\s+(\d+) (.+)$`),
	"committed_as":     regexp.MustCompile(`^Committed_AS:\s+(\d+) (.+)$`),
	"vmalloc_total":    regexp.MustCompile(`^VmallocTotal:\s+(\d+) (.+)$`),
	"vmalloc_used":     regexp.MustCompile(`^VmallocUsed:\s+(\d+) (.+)$`),
	"vmalloc_chunk":    regexp.MustCompile(`^VmallocChunk:\s+(\d+) (.+)$`),
	"swap_cached":      regexp.MustCompile(`^SwapCached:\s+(\d+) (.+)$`),
	"swap_total":       regexp.MustCompile(`^SwapTotal:\s+(\d+) (.+)$`),
	"swap_free":        regexp.MustCompile(`^SwapFree:\s+(\d+) (.+)$`),
}

// MemoryGenerator collects the host's memory specs.
type MemoryGenerator struct {
}

// Key XXX
func (g *MemoryGenerator) Key() string {
	return "memory"
}

var memoryLogger = logging.GetLogger("spec.memory")

// Generate XXX
func (g *MemoryGenerator) Generate() (interface{}, error) {
	file, err := os.Open("/proc/meminfo")
	if err != nil {
		memoryLogger.Errorf("Failed (skip this spec): %s", err)
		return nil, err
	}

	scanner := bufio.NewScanner(file)

	result := make(map[string]interface{})
	for scanner.Scan() {
		line := scanner.Text()

		for k, v := range memItems {
			if matches := v.FindStringSubmatch(line); matches != nil {
				// ex.) MemTotal:        3916792 kB
				// matches[1] = 3916792, matches[2] = kB
				result[k] = matches[1] + matches[2]
				break
			}
		}
	}
	if err := scanner.Err(); err != nil {
		memoryLogger.Errorf("Failed (skip this spec): %s", err)
		return nil, err
	}

	return result, nil
}
<commit_msg>reduce number of regexp and improve performance for memory spec on linux<commit_after>// +build linux

package linux

import (
	"bufio"
	"io"
	"os"
	"strings"

	"github.com/mackerelio/golib/logging"
)

var memItems = map[string]string{
	"MemTotal:":     "total",
	"MemFree:":      "free",
	"Buffers:":      "buffers",
	"Cached:":       "cached",
	"Active:":       "active",
	"Inactive:":     "inactive",
	"HighTotal:":    "high_total",
	"HighFree:":     "high_free",
	"LowTotal:":     "low_total",
	"LowFree:":      "low_free",
	"Dirty:":        "dirty",
	"Writeback:":    "writeback",
	"AnonPages:":    "anon_pages",
	"Mapped:":       "mapped",
	"Slab:":         "slab",
	"SReclaimable:": "slab_reclaimable",
	"SUnreclaim:":   "slab_unreclaim",
	"PageTables:":   "page_tables",
	"NFS_Unstable:": "nfs_unstable",
	"Bounce:":       "bounce",
	"CommitLimit:":  "commit_limit",
	"Committed_AS:": "committed_as",
	"VmallocTotal:": "vmalloc_total",
	"VmallocUsed:":  "vmalloc_used",
	"VmallocChunk:": "vmalloc_chunk",
	"SwapCached:":   "swap_cached",
	"SwapTotal:":    "swap_total",
	"SwapFree:":     "swap_free",
}

// MemoryGenerator collects the host's memory specs.
type MemoryGenerator struct {
}

// Key XXX
func (g *MemoryGenerator) Key() string {
	return "memory"
}

var memoryLogger = logging.GetLogger("spec.memory")

// Generate XXX
func (g *MemoryGenerator) Generate() (interface{}, error) {
	file, err := os.Open("/proc/meminfo")
	if err != nil {
		memoryLogger.Errorf("Failed (skip this spec): %s", err)
		return nil, err
	}
	defer file.Close()
	return generateMemorySpec(file)
}

func generateMemorySpec(out io.Reader) (map[string]string, error) {
	scanner := bufio.NewScanner(out)

	result := make(map[string]string)
	for scanner.Scan() {
		fields := strings.Fields(scanner.Text())
		if len(fields) < 2 {
			continue
		}
		if k, ok := memItems[fields[0]]; ok {
			// ex) MemTotal:        3916792 kB
			//       -> "total": "3916782kB"
			result[k] = strings.Join(fields[1:], "")
		}
	}
	if err := scanner.Err(); err != nil {
		memoryLogger.Errorf("Failed (skip this spec): %s", err)
		return nil, err
	}

	return result, nil
}
<|endoftext|>


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

package http

import (
	"io"
	"net/http"

	"github.com/astaxie/beego/session"
)

type Context struct {
	sess session.SessionStore

	Writer io.Writer

	ResponseWriter http.ResponseWriter
	Request        *http.Request
}

// New a Context
func NewContext(w http.ResponseWriter, r *http.Request, sess session.SessionStore) *Context {
	return &Context{
		sess:           sess,
		ResponseWriter: w,
		Request:        r,
	}
}
func (cxt *Context) WriteString(s string) (int, error) {
	return cxt.ResponseWriter.Write([]byte(s))
}
func (cxt *Context) GetForm(key string) string {
	if cxt.Request.Form == nil {
		cxt.Request.ParseForm()
	}
	return cxt.Request.FormValue(key)
}
func (cxt *Context) GetSess() session.SessionStore {
	if cxt.sess == nil {
		// Get the session
		cxt.sess = Sessions.SessionStart(cxt.ResponseWriter, cxt.Request)
	}
	return cxt.sess
}

// Redirect does redirection to localurl with http header status code.
// It sends http response header directly.
func (ctx *Context) Redirect(status int, localurl string) {
	ctx.ResponseWriter.Header().Add("Location", localurl)
	ctx.ResponseWriter.WriteHeader(status)
}

func (cxt *Context) finished() {
	if cxt.sess != nil {
		cxt.sess.SessionRelease(cxt.ResponseWriter)
	}
}

type Writer struct {
	w      io.Writer
	encode string
}

func NewWriter(w io.Writer, encode string) *Writer {
	return &Writer{w, encode}
}
func (this *Writer) Write(data []byte) (int, error) {
	// TODO encode
	return this.w.Write(data)
}

type Reader struct {
	body   io.ReadCloser
	encode string
}

func NewReader(body io.ReadCloser, encode string) *Reader {
	return &Reader{body, encode}
}
func (this *Reader) Read(data []byte) (int, error) {
	// TODO encode
	return this.Read(data)
}
<commit_msg>sync copy<commit_after>// Copyright © 2014 Alienero. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package http

import (
	"io"
	"net/http"

	"github.com/astaxie/beego/session"
)

type Context struct {
	sess session.SessionStore

	Out *Writer
	In  *Reader

	ResponseWriter http.ResponseWriter
	Request        *http.Request
}

// New a Context
func NewContext(w http.ResponseWriter, r *http.Request, sess session.SessionStore) *Context {
	return &Context{
		sess:           sess,
		ResponseWriter: w,
		Request:        r,
	}
}
func (cxt *Context) WriteString(s string) (int, error) {
	return cxt.Out.Write([]byte(s))
}
func (cxt *Context) GetForm(key string) string {
	if cxt.Request.Form == nil {
		cxt.Request.ParseForm()
	}
	return cxt.Request.FormValue(key)
}
func (cxt *Context) GetSess() session.SessionStore {
	if cxt.sess == nil {
		// Get the session
		cxt.sess = Sessions.SessionStart(cxt.ResponseWriter, cxt.Request)
	}
	return cxt.sess
}

// Redirect does redirection to localurl with http header status code.
// It sends http response header directly.
func (ctx *Context) Redirect(status int, localurl string) {
	ctx.ResponseWriter.Header().Add("Location", localurl)
	ctx.ResponseWriter.WriteHeader(status)
}

func (cxt *Context) finished() {
	if cxt.sess != nil {
		cxt.sess.SessionRelease(cxt.ResponseWriter)
	}
}

type Writer struct {
	w      io.Writer
	encode string
}

func NewWriter(w io.Writer, encode string) *Writer {
	return &Writer{w, encode}
}
func (this *Writer) Write(data []byte) (int, error) {
	var buff = data
	// TODO encode
	return this.w.Write(data)
}

type Reader struct {
	body   io.ReadCloser
	encode string
}

func NewReader(body io.ReadCloser, encode string) *Reader {
	return &Reader{body, encode}
}
func (this *Reader) Read(data []byte) (n int, err error) {
	buff := make([]byte, len(data))
	n, err = this.Read(buff)
	if err != nil {
		return
	}
	copy(data[:n], buff[:n])
	// TODO encode
	return
}
<|endoftext|>


<commit_before>package special
<commit_msg>special: add naive benchmark<commit_after>package special

import (
	"testing"
)

var result bool

func BenchmarkNaive(b *testing.B) {
	var r bool
	const x = 11
	for n := 0; n < b.N; n++ {
		r = naive(11)
	}
	result = r
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"github.com/jthomas/openwhisk"
)

type Params struct {
	Payload string `json:"payload"`
}

type Result struct {
	Reversed string `json:"reversed"`
}

func reverse_string(to_reverse string) string {
	chars := []rune(to_reverse)
	for i, j := 0, len(chars)-1; i < j; i, j = i+1, j-1 {
		chars[i], chars[j] = chars[j], chars[i]
	}
	return string(chars)
}

func main() {
	openwhisk.RegisterAction(func(value json.RawMessage) (interface{}, error) {
		var params Params
		err := json.Unmarshal(value, &params)
		if err != nil {
			return nil, err
		}
		return Result{Reversed: reverse_string(params.Payload)}, nil
	})
}
<commit_msg>Fixing package reference<commit_after>package main

import (
	"encoding/json"
	"github.com/jthomas/ow"
)

type Params struct {
	Payload string `json:"payload"`
}

type Result struct {
	Reversed string `json:"reversed"`
}

func reverse_string(to_reverse string) string {
	chars := []rune(to_reverse)
	for i, j := 0, len(chars)-1; i < j; i, j = i+1, j-1 {
		chars[i], chars[j] = chars[j], chars[i]
	}
	return string(chars)
}

func main() {
	ow.RegisterAction(func(value json.RawMessage) (interface{}, error) {
		var params Params
		err := json.Unmarshal(value, &params)
		if err != nil {
			return nil, err
		}
		return Result{Reversed: reverse_string(params.Payload)}, nil
	})
}
<|endoftext|>


<commit_before>package tchannel_test

// Copyright (c) 2015 Uber Technologies, Inc.

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

import (
	"math/rand"
	"runtime"
	"sync"
	"testing"
	"time"

	. "github.com/uber/tchannel/golang"

	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
	"github.com/uber/tchannel/golang/raw"
	"github.com/uber/tchannel/golang/testutils"
	"golang.org/x/net/context"
)

type channelState struct {
	ch      *Channel
	closeCh chan struct{}
	closed  bool
}

func makeCall(ch *Channel, hostPort, service string) error {
	ctx, cancel := NewContext(time.Second)
	defer cancel()

	_, _, _, err := raw.Call(ctx, ch, hostPort, service, "test", nil, nil)
	return err
}

// TestCloseStress ensures that once a Channel is closed, it cannot be reached.
func TestCloseStress(t *testing.T) {
	CheckStress(t)

	const numHandlers = 5
	handler := &swapper{t}
	var lock sync.RWMutex
	var wg sync.WaitGroup
	var channels []*channelState

	// Start numHandlers servers, and don't close the connections till they are signalled.
	for i := 0; i < numHandlers; i++ {
		wg.Add(1)
		go func() {
			assert.NoError(t, testutils.WithServer(nil, func(ch *Channel, hostPort string) {
				ch.Register(raw.Wrap(handler), "test")

				chState := &channelState{
					ch:      ch,
					closeCh: make(chan struct{}),
				}

				lock.Lock()
				channels = append(channels, chState)
				lock.Unlock()
				wg.Done()

				// Wait for a close signal.
				<-chState.closeCh

				// Lock until the connection is closed.
				lock.Lock()
				chState.closed = true
			}))
			lock.Unlock()
		}()
	}

	// Wait till all the channels have been registered.
	wg.Wait()

	// Start goroutines to make calls until the test has ended.
	testEnded := make(chan struct{})
	for i := 0; i < 10; i++ {
		go func() {
			for {
				select {
				case <-testEnded:
					return
				default:
					// Keep making requests till the test ends.
				}

				// Get 2 random channels and make a call from one to the other.
				lock.RLock()
				chState1 := channels[rand.Intn(len(channels))]
				chState2 := channels[rand.Intn(len(channels))]
				if chState1 == chState2 {
					lock.RUnlock()
					continue
				}

				// Grab a read lock to make sure channels aren't closed while we call.
				ch1Closed := chState1.closed
				ch2Closed := chState2.closed
				err := makeCall(chState1.ch, chState2.ch.PeerInfo().HostPort, chState2.ch.PeerInfo().ServiceName)
				lock.RUnlock()
				if ch1Closed || ch2Closed {
					assert.Error(t, err, "Call from %v to %v should fail", chState1.ch.PeerInfo(), chState2.ch.PeerInfo())
				} else {
					assert.NoError(t, err, "Call from %v to %v should not fail", chState1.ch.PeerInfo(), chState2.ch.PeerInfo())
				}
			}
		}()
	}

	// Kill connections till all of the connections are dead.
	for i := 0; i < numHandlers; i++ {
		time.Sleep(time.Duration(rand.Intn(50)) * time.Millisecond)
		channels[i].closeCh <- struct{}{}
	}
}

type rawFuncHandler func(context.Context, *raw.Args) (*raw.Res, error)

func (f rawFuncHandler) OnError(_ context.Context, _ error) {}
func (f rawFuncHandler) Handle(ctx context.Context, args *raw.Args) (*raw.Res, error) {
	return f(ctx, args)
}

func registerFunc(ch *Channel, name string,
	f func(ctx context.Context, args *raw.Args) (*raw.Res, error)) {

	ch.Register(raw.Wrap(rawFuncHandler(f)), name)
}

func TestCloseSemantics(t *testing.T) {
	defer testutils.SetTimeout(t, 2*time.Second)()
	ctx, cancel := NewContext(time.Second)
	defer cancel()

	makeServer := func(name string) (*Channel, chan struct{}) {
		ch, err := testutils.NewServer(&testutils.ChannelOpts{ServiceName: name})
		require.NoError(t, err)
		c := make(chan struct{})
		registerFunc(ch, "stream", func(ctx context.Context, args *raw.Args) (*raw.Res, error) {
			<-c
			return &raw.Res{}, nil
		})
		registerFunc(ch, "call", func(ctx context.Context, args *raw.Args) (*raw.Res, error) {
			return &raw.Res{}, nil
		})
		return ch, c
	}

	newClient := func() *Channel {
		ch, err := testutils.NewClient(&testutils.ChannelOpts{ServiceName: "client"})
		require.NoError(t, err)
		return ch
	}

	call := func(from *Channel, to *Channel) error {
		toPeer := to.PeerInfo()
		_, _, _, err := raw.Call(ctx, from, toPeer.HostPort, toPeer.ServiceName, "call", nil, nil)
		return err
	}

	callStream := func(from *Channel, to *Channel) <-chan struct{} {
		c := make(chan struct{})

		toPeer := to.PeerInfo()
		call, err := from.BeginCall(ctx, toPeer.HostPort, toPeer.ServiceName, "stream", nil)
		require.NoError(t, err)
		require.NoError(t, NewArgWriter(call.Arg2Writer()).Write(nil), "write arg2")
		require.NoError(t, NewArgWriter(call.Arg3Writer()).Write(nil), "write arg3")

		go func() {
			var d []byte
			require.NoError(t, NewArgReader(call.Response().Arg2Reader()).Read(&d), "read arg2 from %v to %v", from.PeerInfo(), to.PeerInfo())
			require.NoError(t, NewArgReader(call.Response().Arg3Reader()).Read(&d), "read arg3")
			c <- struct{}{}
		}()

		return c
	}

	s1, s1C := makeServer("s1")
	s2, s2C := makeServer("s2")

	// Make a call from s1 -> s2, and s2 -> s1
	call1 := callStream(s1, s2)
	call2 := callStream(s2, s1)

	// s1 and s2 are both open, so calls to it should be successful.
	require.NoError(t, call(newClient(), s1))
	require.NoError(t, call(newClient(), s2))
	require.NoError(t, call(s1, s2))
	require.NoError(t, call(s2, s1))

	// Close s1, should no longer be able to call it.
	s1.Close()
	assert.Equal(t, ChannelStartClose, s1.State())
	assert.Error(t, call(newClient(), s1), "closed channel should not accept incoming calls")
	require.NoError(t, call(newClient(), s2))

	// Even an existing connection (e.g. from s2) should fail.
	assert.Equal(t, ErrChannelClosed, call(s2, s1), "closed channel should not accept incoming calls")

	require.NoError(t, call(s1, s2),
		"closed channel with pending incoming calls should allow outgoing calls")

	// Once the incoming connection is drained, outgoing calls should fail.
	s1C <- struct{}{}
	<-call2
	assert.Equal(t, ChannelInboundClosed, s1.State())
	require.Error(t, call(s1, s2),
		"closed channel with no pending incoming calls should not allow outgoing calls")

	// Now the channel should be completely closed as there are no pending connections.
	s2C <- struct{}{}
	<-call1
	assert.Equal(t, ChannelClosed, s1.State())
}

func TestCloseGoroutines(t *testing.T) {
	ctx, cancel := NewContext(time.Second)
	defer cancel()

	// Make sure that all client and server Goroutines are closed when a connection is closed.
	ch, err := testutils.NewServer(nil)
	require.NoError(t, err, "NewServer failed")
	ch.Register(raw.Wrap(&testHandler{}), "echo")

	peerInfo := ch.PeerInfo()
	_, _, _, err = raw.Call(ctx, ch, peerInfo.HostPort, peerInfo.ServiceName, "echo", nil, nil)
	assert.NoError(t, err, "Call failed")

	ch.Close()
	assert.Equal(t, ChannelClosed, ch.State())

	// Give a chance for the closed connection to close the read/write goroutines.
	runtime.Gosched()
	VerifyNoBlockedGoroutines(t)
}
<commit_msg>Update test to Close with pending calls<commit_after>package tchannel_test

// Copyright (c) 2015 Uber Technologies, Inc.

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

import (
	"math/rand"
	"runtime"
	"sync"
	"testing"
	"time"

	. "github.com/uber/tchannel/golang"

	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
	"github.com/uber/tchannel/golang/raw"
	"github.com/uber/tchannel/golang/testutils"
	"golang.org/x/net/context"
)

type channelState struct {
	ch      *Channel
	closeCh chan struct{}
	closed  bool
}

func makeCall(ch *Channel, hostPort, service string) error {
	ctx, cancel := NewContext(time.Second)
	defer cancel()

	_, _, _, err := raw.Call(ctx, ch, hostPort, service, "test", nil, nil)
	return err
}

// TestCloseStress ensures that once a Channel is closed, it cannot be reached.
func TestCloseStress(t *testing.T) {
	CheckStress(t)

	const numHandlers = 5
	handler := &swapper{t}
	var lock sync.RWMutex
	var wg sync.WaitGroup
	var channels []*channelState

	// Start numHandlers servers, and don't close the connections till they are signalled.
	for i := 0; i < numHandlers; i++ {
		wg.Add(1)
		go func() {
			assert.NoError(t, testutils.WithServer(nil, func(ch *Channel, hostPort string) {
				ch.Register(raw.Wrap(handler), "test")

				chState := &channelState{
					ch:      ch,
					closeCh: make(chan struct{}),
				}

				lock.Lock()
				channels = append(channels, chState)
				lock.Unlock()
				wg.Done()

				// Wait for a close signal.
				<-chState.closeCh

				// Lock until the connection is closed.
				lock.Lock()
				chState.closed = true
			}))
			lock.Unlock()
		}()
	}

	// Wait till all the channels have been registered.
	wg.Wait()

	// Start goroutines to make calls until the test has ended.
	testEnded := make(chan struct{})
	for i := 0; i < 10; i++ {
		go func() {
			for {
				select {
				case <-testEnded:
					return
				default:
					// Keep making requests till the test ends.
				}

				// Get 2 random channels and make a call from one to the other.
				lock.RLock()
				chState1 := channels[rand.Intn(len(channels))]
				chState2 := channels[rand.Intn(len(channels))]
				if chState1 == chState2 {
					lock.RUnlock()
					continue
				}

				// Grab a read lock to make sure channels aren't closed while we call.
				ch1Closed := chState1.closed
				ch2Closed := chState2.closed
				err := makeCall(chState1.ch, chState2.ch.PeerInfo().HostPort, chState2.ch.PeerInfo().ServiceName)
				lock.RUnlock()
				if ch1Closed || ch2Closed {
					assert.Error(t, err, "Call from %v to %v should fail", chState1.ch.PeerInfo(), chState2.ch.PeerInfo())
				} else {
					assert.NoError(t, err, "Call from %v to %v should not fail", chState1.ch.PeerInfo(), chState2.ch.PeerInfo())
				}
			}
		}()
	}

	// Kill connections till all of the connections are dead.
	for i := 0; i < numHandlers; i++ {
		time.Sleep(time.Duration(rand.Intn(50)) * time.Millisecond)
		channels[i].closeCh <- struct{}{}
	}
}

type simpleHandler struct {
	t *testing.T
	f func(context.Context, *raw.Args) (*raw.Res, error)
}

func (h simpleHandler) OnError(ctx context.Context, err error) {
	h.t.Errorf("simpleHandler OnError: %v %v", ctx, err)
}

func (h simpleHandler) Handle(ctx context.Context, args *raw.Args) (*raw.Res, error) {
	return h.f(ctx, args)
}

func registerFunc(t *testing.T, ch *Channel, name string,
	f func(ctx context.Context, args *raw.Args) (*raw.Res, error)) {
	ch.Register(raw.Wrap(simpleHandler{t, f}), name)
}

func TestCloseSemantics(t *testing.T) {
	defer testutils.SetTimeout(t, 2*time.Second)()
	ctx, cancel := NewContext(time.Second)
	defer cancel()

	makeServer := func(name string) (*Channel, chan struct{}) {
		ch, err := testutils.NewServer(&testutils.ChannelOpts{ServiceName: name})
		require.NoError(t, err)
		c := make(chan struct{})
		registerFunc(t, ch, "stream", func(ctx context.Context, args *raw.Args) (*raw.Res, error) {
			<-c
			return &raw.Res{}, nil
		})
		registerFunc(t, ch, "call", func(ctx context.Context, args *raw.Args) (*raw.Res, error) {
			return &raw.Res{}, nil
		})
		return ch, c
	}

	newClient := func() *Channel {
		ch, err := testutils.NewClient(&testutils.ChannelOpts{ServiceName: "client"})
		require.NoError(t, err)
		return ch
	}

	call := func(from *Channel, to *Channel) error {
		toPeer := to.PeerInfo()
		_, _, _, err := raw.Call(ctx, from, toPeer.HostPort, toPeer.ServiceName, "call", nil, nil)
		return err
	}

	callStream := func(from *Channel, to *Channel) <-chan struct{} {
		c := make(chan struct{})

		toPeer := to.PeerInfo()
		call, err := from.BeginCall(ctx, toPeer.HostPort, toPeer.ServiceName, "stream", nil)
		require.NoError(t, err)
		require.NoError(t, NewArgWriter(call.Arg2Writer()).Write(nil), "write arg2")
		require.NoError(t, NewArgWriter(call.Arg3Writer()).Write(nil), "write arg3")

		go func() {
			var d []byte
			require.NoError(t, NewArgReader(call.Response().Arg2Reader()).Read(&d), "read arg2 from %v to %v", from.PeerInfo(), to.PeerInfo())
			require.NoError(t, NewArgReader(call.Response().Arg3Reader()).Read(&d), "read arg3")
			c <- struct{}{}
		}()

		return c
	}

	s1, s1C := makeServer("s1")
	s2, s2C := makeServer("s2")

	// Make a call from s1 -> s2, and s2 -> s1
	call1 := callStream(s1, s2)
	call2 := callStream(s2, s1)

	// s1 and s2 are both open, so calls to it should be successful.
	require.NoError(t, call(newClient(), s1))
	require.NoError(t, call(newClient(), s2))
	require.NoError(t, call(s1, s2))
	require.NoError(t, call(s2, s1))

	// Close s1, should no longer be able to call it.
	s1.Close()
	assert.Equal(t, ChannelStartClose, s1.State())
	assert.Error(t, call(newClient(), s1), "closed channel should not accept incoming calls")
	require.NoError(t, call(newClient(), s2))

	// Even an existing connection (e.g. from s2) should fail.
	assert.Equal(t, ErrChannelClosed, call(s2, s1), "closed channel should not accept incoming calls")

	require.NoError(t, call(s1, s2),
		"closed channel with pending incoming calls should allow outgoing calls")

	// Once the incoming connection is drained, outgoing calls should fail.
	s1C <- struct{}{}
	<-call2
	assert.Equal(t, ChannelInboundClosed, s1.State())
	require.Error(t, call(s1, s2),
		"closed channel with no pending incoming calls should not allow outgoing calls")

	// Now the channel should be completely closed as there are no pending connections.
	s2C <- struct{}{}
	<-call1
	assert.Equal(t, ChannelClosed, s1.State())
}

func TestCloseGoroutines(t *testing.T) {
	ctx, cancel := NewContext(time.Second)
	defer cancel()

	ch, err := testutils.NewServer(nil)
	require.NoError(t, err, "NewServer failed")

	var connected sync.WaitGroup
	var completed sync.WaitGroup
	blockCall := make(chan struct{})

	registerFunc(t, ch, "echo", func(ctx context.Context, args *raw.Args) (*raw.Res, error) {
		connected.Done()
		<-blockCall
		return &raw.Res{
			Arg2: args.Arg2,
			Arg3: args.Arg3,
		}, nil
	})

	for i := 0; i < 10; i++ {
		connected.Add(1)
		completed.Add(1)
		go func() {
			peerInfo := ch.PeerInfo()
			_, _, _, err = raw.Call(ctx, ch, peerInfo.HostPort, peerInfo.ServiceName, "echo", nil, nil)
			assert.NoError(t, err, "Call failed")
			completed.Done()
		}()
	}

	// Wait for all calls to connect before triggerring the Close (so they do not fail).
	connected.Wait()
	ch.Close()

	// Unblock the calls, and wait for all the calls to complete.
	close(blockCall)
	completed.Wait()

	// Once all calls are complete, the channel should be closed.
	runtime.Gosched()
	assert.Equal(t, ChannelClosed, ch.State())
	runtime.Gosched()
	VerifyNoBlockedGoroutines(t)
}
<|endoftext|>


<commit_before>package pushbullet

import (
	"encoding/json"
	"errors"
	"fmt"
	"net/http"
	"net/http/httptest"
	"net/url"
	"os"
	"testing"
)

func getKey() (k string, err error) {
	k = os.Getenv("APIKEY_PUSHBULLET")
	if len(k) == 0 {
		return k, errors.New("API key env var was not found")
	}
	return
}

func mockHTTP(status int, body string) (*httptest.Server, *Client) {

	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.WriteHeader(status)
		w.Header().Add("content-type", "application/json")
		fmt.Fprintln(w, body)
	}))

	tr := &http.Transport{
		Proxy: func(req *http.Request) (*url.URL, error) {
			return url.Parse(server.URL)
		},
	}
	httpClient := &http.Client{Transport: tr}

	client := &Client{"apikey", server.URL, httpClient}
	return server, client
}

func TestGetUser(t *testing.T) {
	k, err := getKey()
	if err != nil {
		t.Fatal(err)
	}
	c := ClientWithKey(k)
	u, err := c.GetUser()
	if err != nil {
		t.Error(err)
	}
	p, err := json.MarshalIndent(u, "", "  ")
	fmt.Println(string(p))
}

func TestErrorString(t *testing.T) {
	e := &Error{
		ErrorBody: errorBody{
			Message: "Test invalid request",
			Type:    "invalid_request",
			Cat:     "^._.^",
		},
	}
	if e.String() != "Invalid Request: Test invalid request" {
		t.Error("Did not return correct invalid request error string\nReturned:", e.String())
	}
	e = &Error{
		ErrorBody: errorBody{
			Message: "Test server error",
			Type:    "server",
			Cat:     "^._.^",
		},
	}
	if e.String() != "Server Error: Test server error" {
		t.Error("Did not return correct server error string\nReturned:", e.String())
	}
}

// Push - Notes

func TestSendNoteToAll(t *testing.T) {
	// Use the following code in place of the mock calls to test on live api
	// k, err := getKey()
	// if err != nil {
	// 	t.Fatal(err)
	// }
	//c := ClientWithKey(k)
	mockServer, c := mockHTTP(200, "{}")
	defer mockServer.Close()

	err := c.SendNote("Build Test", "This is a test of gopushbullet's SendNote() function.")
	if err != nil {
		t.Error(err)
	}
}

func TestSendNoteFailurePaths(t *testing.T) {
	mockServer, c := mockHTTP(401, "{}")
	defer mockServer.Close()

	err := c.SendNoteToTarget("channel", "testchannelpleaseignore", "Build Test", "This is a test of gopushbullet.")
	if err == nil {
		t.Error(err)
	}
	mockServer, c = mockHTTP(401, "invalid json")
	err = c.SendNoteToTarget("channel", "testchannelpleaseignore", "Build Test", "This is a test of gopushbullet.")
	if err == nil {
		t.Error(err)
	}
}

func TestSendNoteToDevice(t *testing.T) {
	mockServer, c := mockHTTP(200, "{}")
	defer mockServer.Close()

	err := c.SendNoteToTarget("device", "_deviceid_", "Build Test", "This is a test of gopushbullet.")
	if err != nil {
		t.Error(err)
	}
}

func TestSendNoteInvalidTarget(t *testing.T) {
	mockServer, c := mockHTTP(200, "{}")
	defer mockServer.Close()

	err := c.SendNoteToTarget("waffles", "bacon", "Build Test", "This is a test of gopushbullet.")
	if err == nil {
		t.Error(err)
	}
}

func TestSendNoteToChannel(t *testing.T) {
	mockServer, c := mockHTTP(200, "{}")
	defer mockServer.Close()

	err := c.SendNoteToTarget("channel", "testchannelpleaseignore", "Build Test", "This is a test of gopushbullet.")
	if err != nil {
		t.Error(err)
	}
}

func TestSendNoteToEmail(t *testing.T) {
	mockServer, c := mockHTTP(200, "{}")
	defer mockServer.Close()

	err := c.SendNoteToTarget("email", "kariudo@gmail.com", "Build Test", "This is a test of gopushbullet.")
	if err != nil {
		t.Error(err)
	}
}

func TestSendNoteToClientID(t *testing.T) {
	mockServer, c := mockHTTP(200, "{}")
	defer mockServer.Close()

	err := c.SendNoteToTarget("client", "_clientid_", "Build Test", "This is a test of gopushbullet's SendNote() function.")
	if err != nil {
		t.Error(err)
	}
}

// Push - Links
func TestSendLinkToAll(t *testing.T) {
	mockServer, c := mockHTTP(200, "{}")
	defer mockServer.Close()

	err := c.SendLink("Build Test", "This is a test of gopushbullet's SendLink() function.", "http://example.com")
	if err != nil {
		t.Error(err)
	}
}

func TestSendLinkFailurePaths(t *testing.T) {
	mockServer, c := mockHTTP(401, "{}")
	defer mockServer.Close()

	err := c.SendLinkToTarget("channel", "testchannelpleaseignore", "Build Test", "This is a test of gopushbullet's SendLink() function.", "http://example.com")
	if err == nil {
		t.Error(err)
	}
	mockServer, c = mockHTTP(401, "invalid json")
	err = c.SendLinkToTarget("channel", "testchannelpleaseignore", "Build Test", "This is a test of gopushbullet's SendLink() function.", "http://example.com")
	if err == nil {
		t.Error(err)
	}
}

func TestSendLinkToDevice(t *testing.T) {
	mockServer, c := mockHTTP(200, "{}")
	defer mockServer.Close()

	err := c.SendLinkToTarget("device", "_deviceid_", "Build Test", "This is a test of gopushbullet's SendLink() function.", "http://example.com")
	if err != nil {
		t.Error(err)
	}
}

func TestSendLinkInvalidTarget(t *testing.T) {
	mockServer, c := mockHTTP(200, "{}")
	defer mockServer.Close()

	err := c.SendLinkToTarget("waffles", "bacon", "Build Test", "This is a test of gopushbullet's SendLink() function.", "http://example.com")
	if err == nil {
		t.Error(err)
	}
}

func TestSendLinkToChannel(t *testing.T) {
	mockServer, c := mockHTTP(200, "{}")
	defer mockServer.Close()

	err := c.SendLinkToTarget("channel", "testchannelpleaseignore", "Build Test", "This is a test of gopushbullet's SendLink() function.", "http://example.com")
	if err != nil {
		t.Error(err)
	}
}

func TestSendLinkToEmail(t *testing.T) {
	mockServer, c := mockHTTP(200, "{}")
	defer mockServer.Close()

	err := c.SendLinkToTarget("email", "kariudo@gmail.com", "Build Test", "This is a test of gopushbullet's SendLink() function.", "http://example.com")
	if err != nil {
		t.Error(err)
	}
}

func TestSendLinkToClientID(t *testing.T) {
	mockServer, c := mockHTTP(200, "{}")
	defer mockServer.Close()

	err := c.SendLinkToTarget("client", "_clientid_", "Build Test", "This is a test of gopushbullet's SendLink() function.", "http://example.com")
	if err != nil {
		t.Error(err)
	}
}

// Push - Address
func TestSendAddressToAll(t *testing.T) {
	mockServer, c := mockHTTP(200, "{}")
	defer mockServer.Close()

	err := c.SendAddress("Build Test", "Place", "123 Main st., Newtown, CT")
	if err != nil {
		t.Error(err)
	}
}

func TestSendAddressFailurePaths(t *testing.T) {
	mockServer, c := mockHTTP(401, "{}")
	defer mockServer.Close()

	err := c.SendAddressToTarget("channel", "testchannelpleaseignore", "Build Test", "Place", "123 Main st., Newtown, CT")
	if err == nil {
		t.Error(err)
	}
	mockServer, c = mockHTTP(401, "invalid json")
	err = c.SendAddressToTarget("channel", "testchannelpleaseignore", "Build Test", "Place", "123 Main st., Newtown, CT")
	if err == nil {
		t.Error(err)
	}
}

func TestSendAddressToDevice(t *testing.T) {
	mockServer, c := mockHTTP(200, "{}")
	defer mockServer.Close()

	err := c.SendAddressToTarget("device", "_deviceid_", "Build Test", "Place", "123 Main st., Newtown, CT")
	if err != nil {
		t.Error(err)
	}
}

func TestSendAddressInvalidTarget(t *testing.T) {
	mockServer, c := mockHTTP(200, "{}")
	defer mockServer.Close()

	err := c.SendAddressToTarget("waffles", "bacon", "Build Test", "Place", "123 Main st., Newtown, CT")
	if err == nil {
		t.Error(err)
	}
}

func TestSendAddressToChannel(t *testing.T) {
	mockServer, c := mockHTTP(200, "{}")
	defer mockServer.Close()

	err := c.SendAddressToTarget("channel", "testchannelpleaseignore", "Build Test", "Place", "123 Main st., Newtown, CT")
	if err != nil {
		t.Error(err)
	}
}

func TestSendAddressToEmail(t *testing.T) {
	mockServer, c := mockHTTP(200, "{}")
	defer mockServer.Close()

	err := c.SendAddressToTarget("email", "kariudo@gmail.com", "Build Test", "Place", "123 Main st., Newtown, CT")
	if err != nil {
		t.Error(err)
	}
}

func TestSendAddressToClientID(t *testing.T) {
	mockServer, c := mockHTTP(200, "{}")
	defer mockServer.Close()

	err := c.SendAddressToTarget("client", "_clientid_", "Build Test", "Place", "123 Main st., Newtown, CT")
	if err != nil {
		t.Error(err)
	}
}

// Devices tests
func TestGetDevices(t *testing.T) {
	k, err := getKey()
	if err != nil {
		t.Error("Failed to get key")
	}
	c := ClientWithKey(k)
	d, err := c.GetDevices()
	if err != nil {
		t.Error("Failed to get devices: ", err)
	}
	fmt.Println(d)
}
<commit_msg>Tests for checklist pushes<commit_after>package pushbullet

import (
	"encoding/json"
	"errors"
	"fmt"
	"net/http"
	"net/http/httptest"
	"net/url"
	"os"
	"testing"
)

func getKey() (k string, err error) {
	k = os.Getenv("APIKEY_PUSHBULLET")
	if len(k) == 0 {
		return k, errors.New("API key env var was not found")
	}
	return
}

func mockHTTP(status int, body string) (*httptest.Server, *Client) {

	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.WriteHeader(status)
		w.Header().Add("content-type", "application/json")
		fmt.Fprintln(w, body)
	}))

	tr := &http.Transport{
		Proxy: func(req *http.Request) (*url.URL, error) {
			return url.Parse(server.URL)
		},
	}
	httpClient := &http.Client{Transport: tr}

	client := &Client{"apikey", server.URL, httpClient}
	return server, client
}

func TestGetUser(t *testing.T) {
	k, err := getKey()
	if err != nil {
		t.Fatal(err)
	}
	c := ClientWithKey(k)
	u, err := c.GetUser()
	if err != nil {
		t.Error(err)
	}
	p, err := json.MarshalIndent(u, "", "  ")
	fmt.Println(string(p))
}

func TestErrorString(t *testing.T) {
	e := &Error{
		ErrorBody: errorBody{
			Message: "Test invalid request",
			Type:    "invalid_request",
			Cat:     "^._.^",
		},
	}
	if e.String() != "Invalid Request: Test invalid request" {
		t.Error("Did not return correct invalid request error string\nReturned:", e.String())
	}
	e = &Error{
		ErrorBody: errorBody{
			Message: "Test server error",
			Type:    "server",
			Cat:     "^._.^",
		},
	}
	if e.String() != "Server Error: Test server error" {
		t.Error("Did not return correct server error string\nReturned:", e.String())
	}
}

// Devices tests
func TestGetDevices(t *testing.T) {
	k, err := getKey()
	if err != nil {
		t.Error("Failed to get key")
	}
	c := ClientWithKey(k)
	d, err := c.GetDevices()
	if err != nil {
		t.Error("Failed to get devices: ", err)
	}
	fmt.Println(d)
}

// Push - Notes

func TestSendNoteToAll(t *testing.T) {
	// Use the following code in place of the mock calls to test on live api
	// k, err := getKey()
	// if err != nil {
	// 	t.Fatal(err)
	// }
	//c := ClientWithKey(k)
	mockServer, c := mockHTTP(200, "{}")
	defer mockServer.Close()

	err := c.SendNote("Build Test", "This is a test of gopushbullet's SendNote() function.")
	if err != nil {
		t.Error(err)
	}
}

func TestSendNoteFailurePaths(t *testing.T) {
	mockServer, c := mockHTTP(401, "{}")
	defer mockServer.Close()

	err := c.SendNoteToTarget("channel", "testchannelpleaseignore", "Build Test", "This is a test of gopushbullet.")
	if err == nil {
		t.Error(err)
	}
	mockServer, c = mockHTTP(401, "invalid json")
	err = c.SendNoteToTarget("channel", "testchannelpleaseignore", "Build Test", "This is a test of gopushbullet.")
	if err == nil {
		t.Error(err)
	}
}

func TestSendNoteToDevice(t *testing.T) {
	mockServer, c := mockHTTP(200, "{}")
	defer mockServer.Close()

	err := c.SendNoteToTarget("device", "_deviceid_", "Build Test", "This is a test of gopushbullet.")
	if err != nil {
		t.Error(err)
	}
}

func TestSendNoteInvalidTarget(t *testing.T) {
	mockServer, c := mockHTTP(200, "{}")
	defer mockServer.Close()

	err := c.SendNoteToTarget("waffles", "bacon", "Build Test", "This is a test of gopushbullet.")
	if err == nil {
		t.Error(err)
	}
}

func TestSendNoteToChannel(t *testing.T) {
	mockServer, c := mockHTTP(200, "{}")
	defer mockServer.Close()

	err := c.SendNoteToTarget("channel", "testchannelpleaseignore", "Build Test", "This is a test of gopushbullet.")
	if err != nil {
		t.Error(err)
	}
}

func TestSendNoteToEmail(t *testing.T) {
	mockServer, c := mockHTTP(200, "{}")
	defer mockServer.Close()

	err := c.SendNoteToTarget("email", "kariudo@gmail.com", "Build Test", "This is a test of gopushbullet.")
	if err != nil {
		t.Error(err)
	}
}

func TestSendNoteToClientID(t *testing.T) {
	mockServer, c := mockHTTP(200, "{}")
	defer mockServer.Close()

	err := c.SendNoteToTarget("client", "_clientid_", "Build Test", "This is a test of gopushbullet's SendNote() function.")
	if err != nil {
		t.Error(err)
	}
}

// Push - Links
func TestSendLinkToAll(t *testing.T) {
	mockServer, c := mockHTTP(200, "{}")
	defer mockServer.Close()

	err := c.SendLink("Build Test", "This is a test of gopushbullet's SendLink() function.", "http://example.com")
	if err != nil {
		t.Error(err)
	}
}

func TestSendLinkFailurePaths(t *testing.T) {
	mockServer, c := mockHTTP(401, "{}")
	defer mockServer.Close()

	err := c.SendLinkToTarget("channel", "testchannelpleaseignore", "Build Test", "This is a test of gopushbullet's SendLink() function.", "http://example.com")
	if err == nil {
		t.Error(err)
	}
	mockServer, c = mockHTTP(401, "invalid json")
	err = c.SendLinkToTarget("channel", "testchannelpleaseignore", "Build Test", "This is a test of gopushbullet's SendLink() function.", "http://example.com")
	if err == nil {
		t.Error(err)
	}
}

func TestSendLinkToDevice(t *testing.T) {
	mockServer, c := mockHTTP(200, "{}")
	defer mockServer.Close()

	err := c.SendLinkToTarget("device", "_deviceid_", "Build Test", "This is a test of gopushbullet's SendLink() function.", "http://example.com")
	if err != nil {
		t.Error(err)
	}
}

func TestSendLinkInvalidTarget(t *testing.T) {
	mockServer, c := mockHTTP(200, "{}")
	defer mockServer.Close()

	err := c.SendLinkToTarget("waffles", "bacon", "Build Test", "This is a test of gopushbullet's SendLink() function.", "http://example.com")
	if err == nil {
		t.Error(err)
	}
}

func TestSendLinkToChannel(t *testing.T) {
	mockServer, c := mockHTTP(200, "{}")
	defer mockServer.Close()

	err := c.SendLinkToTarget("channel", "testchannelpleaseignore", "Build Test", "This is a test of gopushbullet's SendLink() function.", "http://example.com")
	if err != nil {
		t.Error(err)
	}
}

func TestSendLinkToEmail(t *testing.T) {
	mockServer, c := mockHTTP(200, "{}")
	defer mockServer.Close()

	err := c.SendLinkToTarget("email", "kariudo@gmail.com", "Build Test", "This is a test of gopushbullet's SendLink() function.", "http://example.com")
	if err != nil {
		t.Error(err)
	}
}

func TestSendLinkToClientID(t *testing.T) {
	mockServer, c := mockHTTP(200, "{}")
	defer mockServer.Close()

	err := c.SendLinkToTarget("client", "_clientid_", "Build Test", "This is a test of gopushbullet's SendLink() function.", "http://example.com")
	if err != nil {
		t.Error(err)
	}
}

// Push - Address
func TestSendAddressToAll(t *testing.T) {
	mockServer, c := mockHTTP(200, "{}")
	defer mockServer.Close()

	err := c.SendAddress("Build Test", "Place", "123 Main st., Newtown, CT")
	if err != nil {
		t.Error(err)
	}
}

func TestSendAddressFailurePaths(t *testing.T) {
	mockServer, c := mockHTTP(401, "{}")
	defer mockServer.Close()

	err := c.SendAddressToTarget("channel", "testchannelpleaseignore", "Build Test", "Place", "123 Main st., Newtown, CT")
	if err == nil {
		t.Error(err)
	}
	mockServer, c = mockHTTP(401, "invalid json")
	err = c.SendAddressToTarget("channel", "testchannelpleaseignore", "Build Test", "Place", "123 Main st., Newtown, CT")
	if err == nil {
		t.Error(err)
	}
}

func TestSendAddressToDevice(t *testing.T) {
	mockServer, c := mockHTTP(200, "{}")
	defer mockServer.Close()

	err := c.SendAddressToTarget("device", "_deviceid_", "Build Test", "Place", "123 Main st., Newtown, CT")
	if err != nil {
		t.Error(err)
	}
}

func TestSendAddressInvalidTarget(t *testing.T) {
	mockServer, c := mockHTTP(200, "{}")
	defer mockServer.Close()

	err := c.SendAddressToTarget("waffles", "bacon", "Build Test", "Place", "123 Main st., Newtown, CT")
	if err == nil {
		t.Error(err)
	}
}

func TestSendAddressToChannel(t *testing.T) {
	mockServer, c := mockHTTP(200, "{}")
	defer mockServer.Close()

	err := c.SendAddressToTarget("channel", "testchannelpleaseignore", "Build Test", "Place", "123 Main st., Newtown, CT")
	if err != nil {
		t.Error(err)
	}
}

func TestSendAddressToEmail(t *testing.T) {
	mockServer, c := mockHTTP(200, "{}")
	defer mockServer.Close()

	err := c.SendAddressToTarget("email", "kariudo@gmail.com", "Build Test", "Place", "123 Main st., Newtown, CT")
	if err != nil {
		t.Error(err)
	}
}

func TestSendAddressToClientID(t *testing.T) {
	mockServer, c := mockHTTP(200, "{}")
	defer mockServer.Close()

	err := c.SendAddressToTarget("client", "_clientid_", "Build Test", "Place", "123 Main st., Newtown, CT")

	if err != nil {
		t.Error(err)
	}
}

// Push - Checklist
func TestSendChecklistToAll(t *testing.T) {
	mockServer, c := mockHTTP(200, "{}")
	defer mockServer.Close()

	err := c.SendChecklist("Build Test", []string{"item1", "item2", "item3"})
	if err != nil {
		t.Error(err)
	}
}

func TestSendChecklistFailurePaths(t *testing.T) {
	mockServer, c := mockHTTP(401, "{}")
	defer mockServer.Close()

	err := c.SendChecklistToTarget("channel", "testchannelpleaseignore", "Build Test", []string{"item1", "item2", "item3"})
	if err == nil {
		t.Error(err)
	}
	mockServer, c = mockHTTP(401, "invalid json")
	err = c.SendChecklistToTarget("channel", "testchannelpleaseignore", "Build Test", []string{"item1", "item2", "item3"})
	if err == nil {
		t.Error(err)
	}
}

func TestSendChecklistToDevice(t *testing.T) {
	mockServer, c := mockHTTP(200, "{}")
	defer mockServer.Close()

	err := c.SendChecklistToTarget("device", "_deviceid_", "Build Test", []string{"item1", "item2", "item3"})
	if err != nil {
		t.Error(err)
	}
}

func TestSendChecklistInvalidTarget(t *testing.T) {
	mockServer, c := mockHTTP(200, "{}")
	defer mockServer.Close()

	err := c.SendChecklistToTarget("waffles", "bacon", "Build Test", []string{"item1", "item2", "item3"})
	if err == nil {
		t.Error(err)
	}
}

func TestSendChecklistToChannel(t *testing.T) {
	mockServer, c := mockHTTP(200, "{}")
	defer mockServer.Close()

	err := c.SendChecklistToTarget("channel", "testchannelpleaseignore", "Build Test", []string{"item1", "item2", "item3"})
	if err != nil {
		t.Error(err)
	}
}

func TestSendChecklistToEmail(t *testing.T) {
	mockServer, c := mockHTTP(200, "{}")
	defer mockServer.Close()

	err := c.SendChecklistToTarget("email", "kariudo@gmail.com", "Build Test", []string{"item1", "item2", "item3"})
	if err != nil {
		t.Error(err)
	}
}

func TestSendChecklistToClientID(t *testing.T) {
	mockServer, c := mockHTTP(200, "{}")
	defer mockServer.Close()

	err := c.SendChecklistToTarget("client", "_clientid_", "Build Test", []string{"item1", "item2", "item3"})

	if err != nil {
		t.Error(err)
	}
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2013 Dave Collins <dave@davec.name>
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

package spew_test

import (
	"bytes"
	"fmt"
	"github.com/davecgh/go-spew/spew"
	"io/ioutil"
	"os"
	"testing"
)

// Config states with various settings.
var scsDefault = spew.NewDefaultConfig()
var scsNoMethods = &spew.ConfigState{Indent: " ", DisableMethods: true}
var scsNoPmethods = &spew.ConfigState{Indent: " ", DisablePointerMethods: true}

// Variables for tests on types which implement Stringer interface with and
// without a pointer receiver.
var ts = stringer("test")
var tps = pstringer("test")

// spewFunc is used to identify which public function of the spew package or
// ConfigState a test applies to.
type spewFunc int

const (
	fCSFdump spewFunc = iota
	fCSFprint
	fCSFprintf
	fCSFprintln
	fCSPrint
	fCSPrintln
	fCSErrorf
	fCSNewFormatter
	fErrorf
	fFprint
	fFprintln
	fPrint
	fPrintln
)

// Map of spewFunc values to names for pretty printing.
var spewFuncStrings = map[spewFunc]string{
	fCSFdump:        "ConfigState.Fdump",
	fCSFprint:       "ConfigState.Fprint",
	fCSFprintf:      "ConfigState.Fprintf",
	fCSFprintln:     "ConfigState.Fprintln",
	fCSPrint:        "ConfigState.Print",
	fCSPrintln:      "ConfigState.Println",
	fCSErrorf:       "ConfigState.Errorf",
	fCSNewFormatter: "ConfigState.NewFormatter",
	fErrorf:         "spew.Errorf",
	fFprint:         "spew.Fprint",
	fFprintln:       "spew.Fprintln",
	fPrint:          "spew.Print",
	fPrintln:        "spew.Println",
}

func (f spewFunc) String() string {
	if s, ok := spewFuncStrings[f]; ok {
		return s
	}
	return fmt.Sprintf("Unknown spewFunc (%d)", int(f))
}

// spewTest is used to describe a test to be performed against the public
// functions of the spew package or ConfigState.
type spewTest struct {
	cs     *spew.ConfigState
	f      spewFunc
	format string
	in     interface{}
	want   string
}

// spewTests houses the tests to be performed against the public functions of
// the spew package and ConfigState.
//
// These tests are only intended to ensure the public functions are exercised
// and are intentionally not exhaustive of types.  The exhaustive type
// tests are handled in the dump and format tests.
var spewTests = []spewTest{
	{scsDefault, fCSFdump, "", int8(127), "(int8) 127\n"},
	{scsDefault, fCSFprint, "", int16(32767), "32767"},
	{scsDefault, fCSFprintf, "%v", int32(2147483647), "2147483647"},
	{scsDefault, fCSFprintln, "", int(2147483647), "2147483647\n"},
	{scsDefault, fCSPrint, "", int64(9223372036854775807), "9223372036854775807"},
	{scsDefault, fCSPrintln, "", uint8(255), "255\n"},
	{scsDefault, fCSErrorf, "%#v", uint16(65535), "(uint16)65535"},
	{scsDefault, fCSNewFormatter, "%v", uint32(4294967295), "4294967295"},
	{scsDefault, fErrorf, "%v", uint64(18446744073709551615), "18446744073709551615"},
	{scsDefault, fFprint, "", float32(3.14), "3.14"},
	{scsDefault, fFprintln, "", float64(6.28), "6.28\n"},
	{scsDefault, fPrint, "", true, "true"},
	{scsDefault, fPrintln, "", false, "false\n"},
	{scsNoMethods, fCSFprint, "", ts, "test"},
	{scsNoMethods, fCSFprint, "", &ts, "<*>test"},
	{scsNoMethods, fCSFprint, "", tps, "test"},
	{scsNoMethods, fCSFprint, "", &tps, "<*>test"},
	{scsNoPmethods, fCSFprint, "", ts, "stringer test"},
	{scsNoPmethods, fCSFprint, "", &ts, "<*>stringer test"},
	{scsNoPmethods, fCSFprint, "", tps, "test"},
	{scsNoPmethods, fCSFprint, "", &tps, "<*>stringer test"},
}

// redirStdout is a helper function to return the standard output from f as a
// byte slice.
func redirStdout(f func()) ([]byte, error) {
	tempFile, err := ioutil.TempFile("", "ss-test")
	if err != nil {
		return nil, err
	}
	fileName := tempFile.Name()
	defer os.Remove(fileName) // Ignore error

	origStdout := os.Stdout
	os.Stdout = tempFile
	f()
	os.Stdout = origStdout
	tempFile.Close()

	return ioutil.ReadFile(fileName)
}

// TestSpew executes all of the tests described by spewTests.
func TestSpew(t *testing.T) {
	t.Logf("Running %d tests", len(spewTests))
	for i, test := range spewTests {
		buf := new(bytes.Buffer)
		switch test.f {
		case fCSFdump:
			test.cs.Fdump(buf, test.in)

		case fCSFprint:
			test.cs.Fprint(buf, test.in)

		case fCSFprintf:
			test.cs.Fprintf(buf, test.format, test.in)

		case fCSFprintln:
			test.cs.Fprintln(buf, test.in)

		case fCSPrint:
			b, err := redirStdout(func() { test.cs.Print(test.in) })
			if err != nil {
				t.Errorf("%v #%d %v", test.f, i, err)
				continue
			}
			buf.Write(b)

		case fCSPrintln:
			b, err := redirStdout(func() { test.cs.Println(test.in) })
			if err != nil {
				t.Errorf("%v #%d %v", test.f, i, err)
				continue
			}
			buf.Write(b)

		case fCSErrorf:
			err := test.cs.Errorf(test.format, test.in)
			buf.WriteString(err.Error())

		case fCSNewFormatter:
			fmt.Fprintf(buf, test.format, test.cs.NewFormatter(test.in))

		case fErrorf:
			err := spew.Errorf(test.format, test.in)
			buf.WriteString(err.Error())

		case fFprint:
			spew.Fprint(buf, test.in)

		case fFprintln:
			spew.Fprintln(buf, test.in)

		case fPrint:
			b, err := redirStdout(func() { spew.Print(test.in) })
			if err != nil {
				t.Errorf("%v #%d %v", test.f, i, err)
				continue
			}
			buf.Write(b)

		case fPrintln:
			b, err := redirStdout(func() { spew.Println(test.in) })
			if err != nil {
				t.Errorf("%v #%d %v", test.f, i, err)
				continue
			}
			buf.Write(b)

		default:
			t.Errorf("%v #%d unrecognized function", test.f, i)
			continue
		}
		s := buf.String()
		if test.want != s {
			t.Errorf("ConfigState #%d\n got: %s want: %s", i, s, test.want)
			continue
		}
	}
}
<commit_msg>Move spew tests init into its own function.<commit_after>/*
 * Copyright (c) 2013 Dave Collins <dave@davec.name>
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

package spew_test

import (
	"bytes"
	"fmt"
	"github.com/davecgh/go-spew/spew"
	"io/ioutil"
	"os"
	"testing"
)

// spewFunc is used to identify which public function of the spew package or
// ConfigState a test applies to.
type spewFunc int

const (
	fCSFdump spewFunc = iota
	fCSFprint
	fCSFprintf
	fCSFprintln
	fCSPrint
	fCSPrintln
	fCSErrorf
	fCSNewFormatter
	fErrorf
	fFprint
	fFprintln
	fPrint
	fPrintln
)

// Map of spewFunc values to names for pretty printing.
var spewFuncStrings = map[spewFunc]string{
	fCSFdump:        "ConfigState.Fdump",
	fCSFprint:       "ConfigState.Fprint",
	fCSFprintf:      "ConfigState.Fprintf",
	fCSFprintln:     "ConfigState.Fprintln",
	fCSPrint:        "ConfigState.Print",
	fCSPrintln:      "ConfigState.Println",
	fCSErrorf:       "ConfigState.Errorf",
	fCSNewFormatter: "ConfigState.NewFormatter",
	fErrorf:         "spew.Errorf",
	fFprint:         "spew.Fprint",
	fFprintln:       "spew.Fprintln",
	fPrint:          "spew.Print",
	fPrintln:        "spew.Println",
}

func (f spewFunc) String() string {
	if s, ok := spewFuncStrings[f]; ok {
		return s
	}
	return fmt.Sprintf("Unknown spewFunc (%d)", int(f))
}

// spewTest is used to describe a test to be performed against the public
// functions of the spew package or ConfigState.
type spewTest struct {
	cs     *spew.ConfigState
	f      spewFunc
	format string
	in     interface{}
	want   string
}

// spewTests houses the tests to be performed against the public functions of
// the spew package and ConfigState.
//
// These tests are only intended to ensure the public functions are exercised
// and are intentionally not exhaustive of types.  The exhaustive type
// tests are handled in the dump and format tests.
var spewTests []spewTest

// redirStdout is a helper function to return the standard output from f as a
// byte slice.
func redirStdout(f func()) ([]byte, error) {
	tempFile, err := ioutil.TempFile("", "ss-test")
	if err != nil {
		return nil, err
	}
	fileName := tempFile.Name()
	defer os.Remove(fileName) // Ignore error

	origStdout := os.Stdout
	os.Stdout = tempFile
	f()
	os.Stdout = origStdout
	tempFile.Close()

	return ioutil.ReadFile(fileName)
}

func initSpewTests() {
	// Config states with various settings.
	scsDefault := spew.NewDefaultConfig()
	scsNoMethods := &spew.ConfigState{Indent: " ", DisableMethods: true}
	scsNoPmethods := &spew.ConfigState{Indent: " ", DisablePointerMethods: true}
	scsMaxDepth := &spew.ConfigState{Indent: " ", MaxDepth: 1}

	// Variables for tests on types which implement Stringer interface with and
	// without a pointer receiver.
	ts := stringer("test")
	tps := pstringer("test")

	spewTests = []spewTest{
		{scsDefault, fCSFdump, "", int8(127), "(int8) 127\n"},
		{scsDefault, fCSFprint, "", int16(32767), "32767"},
		{scsDefault, fCSFprintf, "%v", int32(2147483647), "2147483647"},
		{scsDefault, fCSFprintln, "", int(2147483647), "2147483647\n"},
		{scsDefault, fCSPrint, "", int64(9223372036854775807), "9223372036854775807"},
		{scsDefault, fCSPrintln, "", uint8(255), "255\n"},
		{scsDefault, fCSErrorf, "%#v", uint16(65535), "(uint16)65535"},
		{scsDefault, fCSNewFormatter, "%v", uint32(4294967295), "4294967295"},
		{scsDefault, fErrorf, "%v", uint64(18446744073709551615), "18446744073709551615"},
		{scsDefault, fFprint, "", float32(3.14), "3.14"},
		{scsDefault, fFprintln, "", float64(6.28), "6.28\n"},
		{scsDefault, fPrint, "", true, "true"},
		{scsDefault, fPrintln, "", false, "false\n"},
		{scsNoMethods, fCSFprint, "", ts, "test"},
		{scsNoMethods, fCSFprint, "", &ts, "<*>test"},
		{scsNoMethods, fCSFprint, "", tps, "test"},
		{scsNoMethods, fCSFprint, "", &tps, "<*>test"},
		{scsNoPmethods, fCSFprint, "", ts, "stringer test"},
		{scsNoPmethods, fCSFprint, "", &ts, "<*>stringer test"},
		{scsNoPmethods, fCSFprint, "", tps, "test"},
		{scsNoPmethods, fCSFprint, "", &tps, "<*>stringer test"},
		{scsMaxDepth, fCSFprint, "", &tps, "<*>stringer test"},
	}
}

// TestSpew executes all of the tests described by spewTests.
func TestSpew(t *testing.T) {
	initSpewTests()

	t.Logf("Running %d tests", len(spewTests))
	for i, test := range spewTests {
		buf := new(bytes.Buffer)
		switch test.f {
		case fCSFdump:
			test.cs.Fdump(buf, test.in)

		case fCSFprint:
			test.cs.Fprint(buf, test.in)

		case fCSFprintf:
			test.cs.Fprintf(buf, test.format, test.in)

		case fCSFprintln:
			test.cs.Fprintln(buf, test.in)

		case fCSPrint:
			b, err := redirStdout(func() { test.cs.Print(test.in) })
			if err != nil {
				t.Errorf("%v #%d %v", test.f, i, err)
				continue
			}
			buf.Write(b)

		case fCSPrintln:
			b, err := redirStdout(func() { test.cs.Println(test.in) })
			if err != nil {
				t.Errorf("%v #%d %v", test.f, i, err)
				continue
			}
			buf.Write(b)

		case fCSErrorf:
			err := test.cs.Errorf(test.format, test.in)
			buf.WriteString(err.Error())

		case fCSNewFormatter:
			fmt.Fprintf(buf, test.format, test.cs.NewFormatter(test.in))

		case fErrorf:
			err := spew.Errorf(test.format, test.in)
			buf.WriteString(err.Error())

		case fFprint:
			spew.Fprint(buf, test.in)

		case fFprintln:
			spew.Fprintln(buf, test.in)

		case fPrint:
			b, err := redirStdout(func() { spew.Print(test.in) })
			if err != nil {
				t.Errorf("%v #%d %v", test.f, i, err)
				continue
			}
			buf.Write(b)

		case fPrintln:
			b, err := redirStdout(func() { spew.Println(test.in) })
			if err != nil {
				t.Errorf("%v #%d %v", test.f, i, err)
				continue
			}
			buf.Write(b)

		default:
			t.Errorf("%v #%d unrecognized function", test.f, i)
			continue
		}
		s := buf.String()
		if test.want != s {
			t.Errorf("ConfigState #%d\n got: %s want: %s", i, s, test.want)
			continue
		}
	}
}
<|endoftext|>