select_test.go 4.2 KB
Newer Older
Amos Wenger's avatar
Amos Wenger committed
1 2 3 4 5 6 7
package hades_test

import (
	"context"
	"testing"

	"crawshaw.io/sqlite"
8
	"github.com/go-xorm/builder"
Amos Wenger's avatar
Amos Wenger committed
9 10
	"github.com/itchio/hades"
	"github.com/itchio/wharf/state"
11
	"github.com/itchio/wharf/wtest"
Amos Wenger's avatar
Amos Wenger committed
12 13 14 15 16 17 18 19 20 21
	"github.com/stretchr/testify/assert"
)

func Test_Select(t *testing.T) {
	consumer := &state.Consumer{
		OnMessage: func(lvl string, message string) {
			t.Logf("[%s] %s", lvl, message)
		},
	}

Amos Wenger's avatar
Amos Wenger committed
22 23 24 25 26
	type Honor struct {
		ID    int64
		Title string
	}

Amos Wenger's avatar
Amos Wenger committed
27 28 29 30
	c, err := hades.NewContext(consumer, &Honor{})
	if err != nil {
		panic(err)
	}
31
	c.Log = true
Amos Wenger's avatar
Amos Wenger committed
32 33 34 35 36 37 38 39 40

	sqlite.Logger = func(code sqlite.ErrorCode, msg []byte) {
		t.Logf("[SQLITE] %d %s", code, string(msg))
	}

	dbpool, err := sqlite.Open("file:memory:?mode=memory", 0, 10)
	if err != nil {
		panic(err)
	}
Amos Wenger's avatar
Amos Wenger committed
41
	defer dbpool.Close()
Amos Wenger's avatar
Amos Wenger committed
42 43 44 45

	conn := dbpool.Get(context.Background().Done())
	defer dbpool.Put(conn)

46
	wtest.Must(t, c.ExecRaw(conn, "CREATE TABLE honors (id INTEGER PRIMARY KEY, title TEXT)", nil))
Amos Wenger's avatar
Amos Wenger committed
47

48 49 50 51 52
	baseHonors := []Honor{
		{ID: 0, Title: "Best Picture"},
		{ID: 1, Title: "Best Supporting Actor"},
		{ID: 2, Title: "Best Muffins"},
		{ID: 3, Title: "Second Best Muffins"},
Amos Wenger's avatar
Amos Wenger committed
53 54
	}

55 56
	for _, h := range baseHonors {
		wtest.Must(t, c.Exec(conn, builder.Insert(builder.Eq{"id": h.ID, "title": h.Title}).Into("honors"), nil))
Amos Wenger's avatar
Amos Wenger committed
57 58
	}

59 60 61
	count, err := c.Count(conn, &Honor{}, builder.NewCond())
	wtest.Must(t, err)
	assert.EqualValues(t, 4, count)
Amos Wenger's avatar
Amos Wenger committed
62

63
	honor := &Honor{}
Amos Wenger's avatar
Amos Wenger committed
64 65 66
	found, err := c.SelectOne(conn, honor, builder.Eq{"id": 3})
	wtest.Must(t, err)
	assert.True(t, found)
Amos Wenger's avatar
Amos Wenger committed
67

68
	var honors []*Honor
69
	wtest.Must(t, c.Select(conn, &honors, builder.Gte{"id": 2}, hades.Search{}))
Amos Wenger's avatar
Amos Wenger committed
70
	assert.EqualValues(t, 2, len(honors))
71 72

	wtest.Must(t, c.ExecRaw(conn, "DROP TABLE honors", nil))
Amos Wenger's avatar
Amos Wenger committed
73 74 75

	// ---------

76
	err = c.Select(conn, []Honor{}, builder.Eq{"id": 3}, hades.Search{})
Amos Wenger's avatar
Amos Wenger committed
77 78
	assert.Error(t, err, "Select must reject non-pointer slice")

79
	err = c.Select(conn, &Honor{}, builder.Eq{"id": 3}, hades.Search{})
Amos Wenger's avatar
Amos Wenger committed
80 81 82 83 84 85 86
	assert.Error(t, err, "Select must reject pointer to non-slice")

	type NotAModel struct {
		ID int64
	}

	var namSlice []*NotAModel
87
	err = c.Select(conn, &namSlice, builder.Eq{"id": 3}, hades.Search{})
Amos Wenger's avatar
Amos Wenger committed
88 89 90 91
	assert.Error(t, err, "Select must reject pointer to slice of non-models")

	// ---------

Amos Wenger's avatar
Amos Wenger committed
92 93 94 95 96
	hhh := &Honor{}
	_, err = c.SelectOne(conn, &hhh, builder.Eq{"id": 3})
	assert.Error(t, err, "SelectOne must pointer to pointer")

	_, err = c.SelectOne(conn, []Honor{}, builder.Eq{"id": 3})
Amos Wenger's avatar
Amos Wenger committed
97 98 99
	assert.Error(t, err, "SelectOne must reject slice")

	answer := 42
Amos Wenger's avatar
Amos Wenger committed
100
	_, err = c.SelectOne(conn, &answer, builder.Eq{"id": 3})
Amos Wenger's avatar
Amos Wenger committed
101 102 103
	assert.Error(t, err, "SelectOne must reject pointer to non-struct")

	nam := &NotAModel{}
Amos Wenger's avatar
Amos Wenger committed
104
	_, err = c.SelectOne(conn, nam, builder.Eq{"id": 3})
Amos Wenger's avatar
Amos Wenger committed
105
	assert.Error(t, err, "SelectOne must reject pointer to non-struct")
Amos Wenger's avatar
Amos Wenger committed
106
}
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138

func Test_SelectSquashed(t *testing.T) {
	consumer := &state.Consumer{
		OnMessage: func(lvl string, message string) {
			t.Logf("[%s] %s", lvl, message)
		},
	}

	type AndroidTraits struct {
		Wise  bool
		Funny bool
	}

	type Android struct {
		ID     int64
		Traits AndroidTraits `hades:"squash"`
	}

	c, err := hades.NewContext(consumer, &Android{})
	if err != nil {
		panic(err)
	}
	c.Log = true

	sqlite.Logger = func(code sqlite.ErrorCode, msg []byte) {
		t.Logf("[SQLITE] %d %s", code, string(msg))
	}

	dbpool, err := sqlite.Open("file:memory:?mode=memory", 0, 10)
	if err != nil {
		panic(err)
	}
Amos Wenger's avatar
Amos Wenger committed
139
	defer dbpool.Close()
140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162

	conn := dbpool.Get(context.Background().Done())
	defer dbpool.Put(conn)

	wtest.Must(t, c.ExecRaw(conn, "CREATE TABLE androids (id INTEGER PRIMARY KEY, wise BOOLEAN, funny BOOLEAN)", nil))
	defer c.ExecRaw(conn, "DROP TABLE androids", nil)

	baseAndroids := []Android{
		Android{ID: 1, Traits: AndroidTraits{Wise: true}},
		Android{ID: 2, Traits: AndroidTraits{Funny: true}},
		Android{ID: 3},
		Android{ID: 4, Traits: AndroidTraits{Wise: true, Funny: true}},
	}

	for _, a := range baseAndroids {
		wtest.Must(t, c.Exec(conn, builder.Insert(builder.Eq{"id": a.ID, "wise": a.Traits.Wise, "funny": a.Traits.Funny}).Into("androids"), nil))
	}

	count, err := c.Count(conn, &Android{}, builder.NewCond())
	wtest.Must(t, err)
	assert.EqualValues(t, 4, count)

	a := &Android{}
Amos Wenger's avatar
Amos Wenger committed
163
	found, err := c.SelectOne(conn, a, builder.Eq{"id": 1})
164
	wtest.Must(t, err)
Amos Wenger's avatar
Amos Wenger committed
165
	assert.True(t, found)
166 167
	assert.EqualValues(t, baseAndroids[0], *a)
}