2021-05-09 20:46:35 -07:00
|
|
|
// Copyright 2021 Team 254. All Rights Reserved.
|
|
|
|
|
// Author: pat@patfairbank.com (Patrick Fairbank)
|
|
|
|
|
|
|
|
|
|
package model
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
|
"testing"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
type validRecord struct {
|
2021-05-12 17:49:05 -07:00
|
|
|
Id int `db:"id"`
|
2021-05-09 20:46:35 -07:00
|
|
|
IntData int
|
|
|
|
|
StringData string
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-12 17:49:05 -07:00
|
|
|
type manualIdRecord struct {
|
|
|
|
|
Id int `db:"id,manual""`
|
|
|
|
|
StringData string
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-09 20:46:35 -07:00
|
|
|
func TestTableSingleCrud(t *testing.T) {
|
|
|
|
|
db := setupTestDb(t)
|
|
|
|
|
defer db.Close()
|
|
|
|
|
|
2022-04-04 20:39:19 -07:00
|
|
|
table, err := newTable[validRecord](db)
|
2021-05-09 20:46:35 -07:00
|
|
|
if !assert.Nil(t, err) {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Test initial create and then read back.
|
|
|
|
|
record := validRecord{IntData: 254, StringData: "The Cheesy Poofs"}
|
|
|
|
|
if assert.Nil(t, table.create(&record)) {
|
2021-05-12 17:49:05 -07:00
|
|
|
assert.Equal(t, 1, record.Id)
|
2021-05-09 20:46:35 -07:00
|
|
|
}
|
2022-04-04 20:39:19 -07:00
|
|
|
record2, err := table.getById(record.Id)
|
|
|
|
|
assert.Equal(t, record, *record2)
|
|
|
|
|
assert.Nil(t, err)
|
2021-05-09 20:46:35 -07:00
|
|
|
|
|
|
|
|
// Test update and then read back.
|
|
|
|
|
record.IntData = 252
|
|
|
|
|
record.StringData = "Teh Chezy Pofs"
|
|
|
|
|
assert.Nil(t, table.update(&record))
|
2022-04-04 20:39:19 -07:00
|
|
|
record2, err = table.getById(record.Id)
|
|
|
|
|
assert.Equal(t, record, *record2)
|
|
|
|
|
assert.Nil(t, err)
|
2021-05-09 20:46:35 -07:00
|
|
|
|
|
|
|
|
// Test delete.
|
|
|
|
|
assert.Nil(t, table.delete(record.Id))
|
2022-04-04 20:39:19 -07:00
|
|
|
record2, err = table.getById(record.Id)
|
|
|
|
|
assert.Nil(t, record2)
|
|
|
|
|
assert.Nil(t, err)
|
2021-05-09 20:46:35 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestTableMultipleCrud(t *testing.T) {
|
|
|
|
|
db := setupTestDb(t)
|
|
|
|
|
defer db.Close()
|
|
|
|
|
|
2022-04-04 20:39:19 -07:00
|
|
|
table, err := newTable[validRecord](db)
|
2021-05-09 20:46:35 -07:00
|
|
|
if !assert.Nil(t, err) {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Insert a few test records.
|
|
|
|
|
record1 := validRecord{IntData: 1, StringData: "One"}
|
|
|
|
|
record2 := validRecord{IntData: 2, StringData: "Two"}
|
|
|
|
|
record3 := validRecord{IntData: 3, StringData: "Three"}
|
|
|
|
|
assert.Nil(t, table.create(&record1))
|
|
|
|
|
assert.Nil(t, table.create(&record2))
|
|
|
|
|
assert.Nil(t, table.create(&record3))
|
|
|
|
|
|
|
|
|
|
// Read all records.
|
2022-04-04 20:39:19 -07:00
|
|
|
records, err := table.getAll()
|
|
|
|
|
assert.Nil(t, err)
|
2021-05-09 20:46:35 -07:00
|
|
|
if assert.Equal(t, 3, len(records)) {
|
|
|
|
|
assert.Equal(t, record1, records[0])
|
|
|
|
|
assert.Equal(t, record2, records[1])
|
|
|
|
|
assert.Equal(t, record3, records[2])
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Truncate the table and verify that the records no longer exist.
|
|
|
|
|
assert.Nil(t, table.truncate())
|
2022-04-04 20:39:19 -07:00
|
|
|
records, err = table.getAll()
|
2021-05-09 20:46:35 -07:00
|
|
|
assert.Equal(t, 0, len(records))
|
2022-04-04 20:39:19 -07:00
|
|
|
assert.Nil(t, err)
|
|
|
|
|
record4, err := table.getById(record1.Id)
|
|
|
|
|
assert.Nil(t, record4)
|
|
|
|
|
assert.Nil(t, err)
|
2021-05-09 20:46:35 -07:00
|
|
|
}
|
|
|
|
|
|
2021-05-12 17:49:05 -07:00
|
|
|
func TestTableWithManualId(t *testing.T) {
|
|
|
|
|
db := setupTestDb(t)
|
|
|
|
|
defer db.Close()
|
|
|
|
|
|
2022-04-04 20:39:19 -07:00
|
|
|
table, err := newTable[manualIdRecord](db)
|
2021-05-12 17:49:05 -07:00
|
|
|
if !assert.Nil(t, err) {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Test initial create and then read back.
|
|
|
|
|
record := manualIdRecord{Id: 254, StringData: "The Cheesy Poofs"}
|
|
|
|
|
if assert.Nil(t, table.create(&record)) {
|
|
|
|
|
assert.Equal(t, 254, record.Id)
|
|
|
|
|
}
|
2022-04-04 20:39:19 -07:00
|
|
|
record2, err := table.getById(record.Id)
|
|
|
|
|
assert.Equal(t, record, *record2)
|
|
|
|
|
assert.Nil(t, err)
|
2021-05-12 17:49:05 -07:00
|
|
|
|
|
|
|
|
// Test update and then read back.
|
|
|
|
|
record.StringData = "Teh Chezy Pofs"
|
|
|
|
|
assert.Nil(t, table.update(&record))
|
2022-04-04 20:39:19 -07:00
|
|
|
record2, err = table.getById(record.Id)
|
|
|
|
|
assert.Equal(t, record, *record2)
|
|
|
|
|
assert.Nil(t, err)
|
2021-05-12 17:49:05 -07:00
|
|
|
|
|
|
|
|
// Test delete.
|
|
|
|
|
assert.Nil(t, table.delete(record.Id))
|
2022-04-04 20:39:19 -07:00
|
|
|
record2, err = table.getById(record.Id)
|
|
|
|
|
assert.Nil(t, record2)
|
|
|
|
|
assert.Nil(t, err)
|
2021-05-12 17:49:05 -07:00
|
|
|
|
|
|
|
|
// Test creating a record with a zero ID.
|
|
|
|
|
record.Id = 0
|
|
|
|
|
err = table.create(&record)
|
|
|
|
|
if assert.NotNil(t, err) {
|
|
|
|
|
assert.Equal(
|
|
|
|
|
t, "can't create manualIdRecord with zero ID since table is configured for manual IDs", err.Error(),
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-09 20:46:35 -07:00
|
|
|
func TestNewTableErrors(t *testing.T) {
|
|
|
|
|
db := setupTestDb(t)
|
|
|
|
|
defer db.Close()
|
|
|
|
|
|
|
|
|
|
// Pass a non-struct as the record type.
|
2022-04-04 20:39:19 -07:00
|
|
|
table, err := newTable[int](db)
|
2021-05-09 20:46:35 -07:00
|
|
|
assert.Nil(t, table)
|
|
|
|
|
if assert.NotNil(t, err) {
|
|
|
|
|
assert.Equal(t, "record type must be a struct; got int", err.Error())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Pass a struct that doesn't have an ID field.
|
|
|
|
|
type recordWithNoId struct {
|
|
|
|
|
StringData string
|
|
|
|
|
}
|
2022-04-04 20:39:19 -07:00
|
|
|
table2, err := newTable[recordWithNoId](db)
|
|
|
|
|
assert.Nil(t, table2)
|
2021-05-09 20:46:35 -07:00
|
|
|
if assert.NotNil(t, err) {
|
|
|
|
|
assert.Equal(t, "struct recordWithNoId has no field tagged as the id", err.Error())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Pass a struct that has a field with the wrong type tagged as the ID.
|
|
|
|
|
type recordWithWrongIdType struct {
|
|
|
|
|
Id bool `db:"id"`
|
|
|
|
|
}
|
2022-04-04 20:39:19 -07:00
|
|
|
table3, err := newTable[recordWithWrongIdType](db)
|
|
|
|
|
assert.Nil(t, table3)
|
2021-05-09 20:46:35 -07:00
|
|
|
if assert.NotNil(t, err) {
|
|
|
|
|
assert.Equal(
|
2021-05-12 17:49:05 -07:00
|
|
|
t, "field in struct recordWithWrongIdType tagged with 'id' must be an int; got bool", err.Error(),
|
2021-05-09 20:46:35 -07:00
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestTableCrudErrors(t *testing.T) {
|
|
|
|
|
db := setupTestDb(t)
|
|
|
|
|
defer db.Close()
|
|
|
|
|
|
2022-04-04 20:39:19 -07:00
|
|
|
table, err := newTable[validRecord](db)
|
2021-05-09 20:46:35 -07:00
|
|
|
if !assert.Nil(t, err) {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Create a record with a non-zero ID.
|
2022-04-04 20:39:19 -07:00
|
|
|
var record validRecord
|
2021-05-09 20:46:35 -07:00
|
|
|
record.Id = 12345
|
|
|
|
|
err = table.create(&record)
|
|
|
|
|
if assert.NotNil(t, err) {
|
2021-05-12 17:49:05 -07:00
|
|
|
assert.Equal(
|
|
|
|
|
t,
|
|
|
|
|
"can't create validRecord with non-zero ID since table is configured for autogenerated IDs: 12345",
|
|
|
|
|
err.Error(),
|
|
|
|
|
)
|
2021-05-09 20:46:35 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Update a record with an ID of zero.
|
|
|
|
|
record.Id = 0
|
|
|
|
|
err = table.update(&record)
|
|
|
|
|
if assert.NotNil(t, err) {
|
|
|
|
|
assert.Equal(t, "can't update validRecord with zero ID", err.Error())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Update a nonexistent record.
|
|
|
|
|
record.Id = 12345
|
|
|
|
|
err = table.update(&record)
|
|
|
|
|
if assert.NotNil(t, err) {
|
|
|
|
|
assert.Equal(t, "can't update non-existent validRecord with ID 12345", err.Error())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Delete a nonexistent record.
|
|
|
|
|
err = table.delete(12345)
|
|
|
|
|
if assert.NotNil(t, err) {
|
|
|
|
|
assert.Equal(t, "can't delete non-existent validRecord with ID 12345", err.Error())
|
|
|
|
|
}
|
|
|
|
|
}
|