Skip to content

Commit

Permalink
Add some more fully fledegd examples
Browse files Browse the repository at this point in the history
  • Loading branch information
Fergus Strange committed Dec 9, 2019
1 parent 8ceb64a commit df3fffd
Show file tree
Hide file tree
Showing 5 changed files with 311 additions and 0 deletions.
162 changes: 162 additions & 0 deletions examples/examples_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
package examples

import (
"fmt"
"net/http"
"net/http/httptest"
"reflect"
"testing"

embeddedpostgres "github.com/fergusstrange/embedded-postgres"
"github.com/jmoiron/sqlx"
_ "github.com/lib/pq"
"github.com/pressly/goose"
)

func Test_GooseMigrations(t *testing.T) {
database := embeddedpostgres.NewDatabase()
if err := database.Start(); err != nil {
t.Fatal(err)
}

defer func() {
if err := database.Stop(); err != nil {
t.Fatal(err)
}
}()

db, err := connect()
if err != nil {
t.Fatal(err)
}

if err := goose.Up(db.DB, "./migrations"); err != nil {
t.Fatal(err)
}
}

func Test_Sqlx_SelectOne(t *testing.T) {
database := embeddedpostgres.NewDatabase()
if err := database.Start(); err != nil {
t.Fatal(err)
}

defer func() {
if err := database.Stop(); err != nil {
t.Fatal(err)
}
}()

db, err := connect()
if err != nil {
t.Fatal(err)
}

rows := make([]int32, 0)

err = db.Select(&rows, "SELECT 1")
if err != nil {
t.Fatal(err)
}

if len(rows) != 1 {
t.Fatal("Expected one row returned")
}
}

func Test_ManyTestsAgainstOneDatabase(t *testing.T) {
database := embeddedpostgres.NewDatabase()
if err := database.Start(); err != nil {
t.Fatal(err)
}

defer func() {
if err := database.Stop(); err != nil {
t.Fatal(err)
}
}()

db, err := connect()
if err != nil {
t.Fatal(err)
}

if err := goose.Up(db.DB, "./migrations"); err != nil {
t.Fatal(err)
}

tests := []func(t *testing.T){
func(t *testing.T) {
rows := make([]BeerCatalogue, 0)
if err := db.Select(&rows, "SELECT * FROM beer_catalogue WHERE UPPER(name) = UPPER('Elvis Juice')"); err != nil {
t.Fatal(err)
}

if len(rows) != 0 {
t.Fatalf("expected 0 rows but got %d", len(rows))
}
},
func(t *testing.T) {
_, err := db.Exec(`INSERT INTO beer_catalogue (name, consumed, rating) VALUES ($1, $2, $3)`,
"Kernal",
true,
99.32)
if err != nil {
t.Fatal(err)
}

actualBeerCatalogue := make([]BeerCatalogue, 0)
if err := db.Select(&actualBeerCatalogue, "SELECT * FROM beer_catalogue WHERE id = 2"); err != nil {
t.Fatal(err)
}

expectedBeerCatalogue := BeerCatalogue{
ID: 2,
Name: "Kernal",
Consumed: true,
Rating: 99.32,
}
if !reflect.DeepEqual(expectedBeerCatalogue, actualBeerCatalogue[0]) {
t.Fatalf("expected %+v did not match actual %+v", expectedBeerCatalogue, actualBeerCatalogue)
}
},
}

for testNumber, test := range tests {
t.Run(fmt.Sprintf("%d", testNumber), test)
}
}

func Test_SimpleHttpWebApp(t *testing.T) {
database := embeddedpostgres.NewDatabase()
if err := database.Start(); err != nil {
t.Fatal(err)
}

defer func() {
if err := database.Stop(); err != nil {
t.Fatal(err)
}
}()

request := httptest.NewRequest("GET", "/beer-catalogue?name=Punk%20IPA", nil)
recorder := httptest.NewRecorder()

NewApp().router.ServeHTTP(recorder, request)

if recorder.Code != http.StatusOK {
t.Fatalf("expected 200 but receieved %d", recorder.Code)
}

expectedPayload := `[{"id":1,"name":"Punk IPA","consumed":true,"rating":68.29}]`
actualPayload := recorder.Body.String()

if actualPayload != expectedPayload {
t.Fatalf("expected %+v but receieved %+v", expectedPayload, actualPayload)
}
}

func connect() (*sqlx.DB, error) {
db, err := sqlx.Connect("postgres", "host=localhost port=5432 user=postgres password=postgres dbname=postgres sslmode=disable")
return db, err
}
14 changes: 14 additions & 0 deletions examples/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
module github.com/fergusstrange/embedded-postgres/examples

go 1.13

replace github.com/fergusstrange/embedded-postgres => ../

require (
github.com/fergusstrange/embedded-postgres v0.0.0
github.com/jmoiron/sqlx v1.2.0
github.com/lib/pq v1.2.0
github.com/pkg/errors v0.8.1 // indirect
github.com/pressly/goose v2.6.0+incompatible
google.golang.org/appengine v1.6.5 // indirect
)
50 changes: 50 additions & 0 deletions examples/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dsnet/compress v0.0.1 h1:PlZu0n3Tuv04TzpfPbrnI0HW/YwodEXDS+oPKahKF0Q=
github.com/dsnet/compress v0.0.1/go.mod h1:Aw8dCMJ7RioblQeTqt88akK31OvO8Dhf5JflhBbQEHo=
github.com/dsnet/golib v0.0.0-20171103203638-1ea166775780/go.mod h1:Lj+Z9rebOhdfkVLjJ8T6VcRQv3SXugXy999NBtR9aFY=
github.com/go-sql-driver/mysql v1.4.0 h1:7LxgVwFb2hIQtMm87NdgAVfXjnt4OePseqT1tKx+opk=
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/jmoiron/sqlx v1.2.0 h1:41Ip0zITnmWNR/vHV+S4m+VoUivnWY5E4OJfLZjCJMA=
github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks=
github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.2.0 h1:LXpIM/LZ5xGFhOpXAQUIMM1HdyqzVYM13zNdjCEEcA0=
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/mattn/go-sqlite3 v1.9.0 h1:pDRiWfl+++eC2FEFRy6jXmQlvp4Yh3z1MJKg4UeYM/4=
github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/mholt/archiver v3.1.1+incompatible h1:1dCVxuqs0dJseYEhi5pl7MYPH9zDa1wBi7mF09cbNkU=
github.com/mholt/archiver v3.1.1+incompatible/go.mod h1:Dh2dOXnSdiLxRiPoVfIr/fI1TwETms9B8CTWfeh7ROU=
github.com/nwaples/rardecode v1.0.0 h1:r7vGuS5akxOnR4JQSkko62RJ1ReCMXxQRPtxsiFMBOs=
github.com/nwaples/rardecode v1.0.0/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0=
github.com/pierrec/lz4 v2.0.5+incompatible h1:2xWsjqPFWcplujydGg4WmhC/6fZqK42wMM8aXeqhl0I=
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pressly/goose v2.6.0+incompatible h1:3f8zIQ8rfgP9tyI0Hmcs2YNAqUCL1c+diLe3iU8Qd/k=
github.com/pressly/goose v2.6.0+incompatible/go.mod h1:m+QHWCqxR3k8D9l7qfzuC/djtlfzxr34mozWDYEu1z8=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/ulikunitz/xz v0.5.6 h1:jGHAfXawEGZQ3blwU5wnWKQJvAraT7Ftq9EXjnXYgt8=
github.com/ulikunitz/xz v0.5.6/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8=
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 h1:nIPpBwaJSVYIxUFsDv3M8ofmx9yWTog9BfvIu0q41lo=
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
google.golang.org/appengine v1.6.5 h1:tycE03LOZYQNhDpS27tcQdAzLCVMaj7QT2SXxebnpCM=
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
15 changes: 15 additions & 0 deletions examples/migrations/20191121120000_init.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
-- +goose Up
-- SQL in this section is executed when the migration is applied.
CREATE TABLE beer_catalogue
(
id SERIAL PRIMARY KEY,
name TEXT,
consumed BOOL DEFAULT TRUE,
rating DOUBLE PRECISION
);

INSERT INTO beer_catalogue (name, consumed, rating)
VALUES ('Punk IPA', true, 68.29);

-- +goose Down
-- SQL in this section is executed when the migration is rolled back.
70 changes: 70 additions & 0 deletions examples/server.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package examples

import (
"encoding/json"
"log"
"net/http"

"github.com/jmoiron/sqlx"
"github.com/pressly/goose"
)

type BeerCatalogue struct {
ID int64 `json:"id"`
Name string `json:"name"`
Consumed bool `json:"consumed"`
Rating float64 `json:"rating"`
}

type App struct {
router *http.ServeMux
}

func (a *App) Start() error {
return http.ListenAndServe("localhost:8080", a.router)
}

func NewApp() *App {
db, err := sqlx.Connect("postgres", "host=localhost port=5432 user=postgres password=postgres dbname=postgres sslmode=disable")
if err != nil {
log.Fatal(err)
}

if err := goose.Up(db.DB, "./migrations"); err != nil {
log.Fatal(err)
}

router := http.NewServeMux()
router.HandleFunc("/beer-catalogue", GetBeer(db))

return &App{router: router}
}

func GetBeer(db *sqlx.DB) func(w http.ResponseWriter, r *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
if beerName := r.URL.Query().Get("name"); beerName != "" {
beers := make([]BeerCatalogue, 0)
if err := db.Select(&beers, "SELECT * FROM beer_catalogue WHERE UPPER(name) = UPPER($1)", beerName); err != nil {
w.WriteHeader(http.StatusInternalServerError)
return
}

jsonPayload, err := json.Marshal(beers)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
return
}

if _, err := w.Write(jsonPayload); err != nil {
w.WriteHeader(http.StatusInternalServerError)
return
}
}

w.WriteHeader(http.StatusBadRequest)
}
}

func main() {
log.Fatal(NewApp().Start())
}

0 comments on commit df3fffd

Please sign in to comment.