Skip to content

Instantly share code, notes, and snippets.

@dpetersen
Last active August 29, 2015 14:13
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dpetersen/4830d82d60885e1ceed2 to your computer and use it in GitHub Desktop.
Save dpetersen/4830d82d60885e1ceed2 to your computer and use it in GitHub Desktop.
Friday demo
package demo
// The Savable interface should be implemented by any resource associated with
// an Account that can be persisted.
type Savable interface {
Save(Account) (string, error)
}
// An Account ties together all records associated with a single client.
//
// There's a lot more you should know about clients, including some code samples:
// a := NewAccount{}
// a.Name = "My Client"
//
// And such. The only problem is that those can't be syntax checked like
// Examples can.
type Account struct {
Name string
}
// NewAccount creates an Account with some default values. Notice that it is
// put in the GoDoc underneath Account because of its return type.
func NewAccount() Account {
return Account{}
}
// SaveResource does some stuff I'm sick of documenting.
func (a Account) SaveResource(s Savable) (string, error) {
id, err := s.Save(a)
return id, err
}
// A Bill can be used to deduct money from the Account's account, which is
// confusing naming on my part.
type Bill struct {
Amount int
}
// Save is interesting because it's part of the interface, and I'd rather just
// document it once for the interface and then not have to do it here. But then
// again, what if there are special rules just for how the Bill saves?
func (b Bill) Save(a Account) (string, error) {
// BUG(dp): Save is useless, but that fact does show up in Known Issues!
return "1001", nil
}
package demo
import (
"errors"
"testing"
"github.com/stretchr/testify/assert"
)
type testResource struct {
SaveCallback func(Account) (string, error)
}
func (r testResource) Save(a Account) (string, error) {
if r.SaveCallback != nil {
return r.SaveCallback(a)
}
return "TestID", nil
}
func TestSuccessfulAccountSave(t *testing.T) {
a := Account{}
r := testResource{
SaveCallback: func(calledAccount Account) (string, error) {
assert.Equal(t, a, calledAccount)
return "TestID", nil
},
}
id, err := a.SaveResource(r)
assert.NoError(t, err)
assert.Equal(t, "TestID", id)
}
func TestErroredAccountSave(t *testing.T) {
a := Account{}
r := testResource{
SaveCallback: func(calledAccount Account) (string, error) {
return "", errors.New("Test Error")
},
}
id, err := a.SaveResource(r)
assert.EqualError(t, err, "Test Error")
assert.Empty(t, id)
}
func TestBillSave(t *testing.T) {
a := Account{}
b := Bill{}
id, err := b.Save(a)
assert.NoError(t, err)
assert.Equal(t, "1001", id)
}
/*
Package demo has a bunch of docs. If I didn't put them in a file like doc.go,
where would I put package-level docs when there isn't a 'main' package? This
seems to be the convention used in the std libs.
Titles Are Awesome
And they can be used wherever. You can also use links, like this one to more
GoDoc tricks:
https://godoc.org/github.com/fluhus/godoc-tricks
And that's about it.
*/
package demo
package demo_test
import (
"fmt"
"github.com/CenturyLinkLabs/demo"
)
func ExampleAccount() {
a := demo.NewAccount()
b := demo.Bill{}
id, _ := a.SaveResource(b)
fmt.Printf("The Bill's ID is: '%s'", id)
// Output: The Bill's ID is: '1001'
}
func ExampleAccount_Save_errored() {
a := demo.NewAccount()
b := demo.Bill{}
_, err := a.SaveResource(b)
err.Error() // Will say something important, blah blah.
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment