-
-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Add specs package * Remove unused param
- Loading branch information
Showing
9 changed files
with
1,696 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
package specs | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/go-rel/rel" | ||
"github.com/go-rel/rel/where" | ||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
// Aggregate tests count specifications. | ||
func Aggregate(t *testing.T, repo rel.Repository) { | ||
// preparte tests data | ||
var ( | ||
user = User{Name: "name1", Gender: "male", Age: 10} | ||
) | ||
|
||
repo.MustInsert(ctx, &user) | ||
|
||
waitForReplication() | ||
|
||
tests := []rel.Query{ | ||
rel.From("users").Where(where.Eq("id", user.ID)), | ||
rel.From("users").Where(where.Eq("name", "name1")), | ||
rel.From("users").Where(where.Eq("age", 10)), | ||
rel.From("users").Where(where.Eq("id", user.ID), where.Eq("name", "name1")), | ||
rel.From("users").Where(where.Eq("id", user.ID), where.Eq("name", "name1"), where.Eq("age", 10)), | ||
rel.From("users").Where(where.Eq("id", user.ID)).OrWhere(where.Eq("name", "name1")), | ||
rel.From("users").Where(where.Eq("id", user.ID)).OrWhere(where.Eq("name", "name1"), where.Eq("age", 10)), | ||
rel.From("users").Where(where.Eq("id", user.ID)).OrWhere(where.Eq("name", "name1")).OrWhere(where.Eq("age", 10)), | ||
rel.From("users").Where(where.Ne("gender", "male")), | ||
rel.From("users").Where(where.Gt("age", 59)), | ||
rel.From("users").Where(where.Gte("age", 60)), | ||
rel.From("users").Where(where.Lt("age", 11)), | ||
rel.From("users").Where(where.Lte("age", 10)), | ||
rel.From("users").Where(where.Nil("note")), | ||
rel.From("users").Where(where.NotNil("name")), | ||
rel.From("users").Where(where.In("id", 1, 2, 3)), | ||
rel.From("users").Where(where.Nin("id", 1, 2, 3)), | ||
rel.From("users").Where(where.Like("name", "name%")), | ||
rel.From("users").Where(where.NotLike("name", "noname%")), | ||
rel.From("users").Where(where.Fragment("id > 0")), | ||
rel.From("users").Where(where.Not(where.Eq("id", 1), where.Eq("name", "name1"), where.Eq("age", 10))), | ||
// this query is not supported. | ||
// group query is automatically removed. | ||
// use all instead for complex aggregation. | ||
rel.From("users").Limit(10), | ||
rel.From("users").Group("gender"), | ||
rel.From("users").Group("age").Having(where.Gt("age", 10)), | ||
} | ||
|
||
for _, query := range tests { | ||
t.Run("Aggregate", func(t *testing.T) { | ||
count, err := repo.Aggregate(ctx, query, "count", "id") | ||
assert.Nil(t, err) | ||
assert.NotZero(t, count) | ||
|
||
sum, err := repo.Aggregate(ctx, query, "sum", "id") | ||
assert.Nil(t, err) | ||
assert.NotZero(t, sum) | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
package specs | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/go-rel/rel" | ||
) | ||
|
||
func createExtra(repo rel.Repository, slug string) Extra { | ||
var user User | ||
repo.MustInsert(ctx, &user) | ||
|
||
extra := Extra{Slug: &slug, UserID: user.ID} | ||
repo.MustInsert(ctx, &extra) | ||
return extra | ||
} | ||
|
||
// UniqueConstraintOnInsert tests unique constraint specifications on insert. | ||
func UniqueConstraintOnInsert(t *testing.T, repo rel.Repository) { | ||
var ( | ||
existing = createExtra(repo, "unique-insert") | ||
err = repo.Insert(ctx, &Extra{Slug: existing.Slug}) | ||
) | ||
|
||
assertConstraint(t, err, rel.UniqueConstraint, "slug") | ||
} | ||
|
||
// UniqueConstraintOnUpdate tests unique constraint specifications on insert. | ||
func UniqueConstraintOnUpdate(t *testing.T, repo rel.Repository) { | ||
var ( | ||
record = createExtra(repo, "unique-record") | ||
existing = createExtra(repo, "unique-update-existing") | ||
err = repo.Update(ctx, &Extra{ID: record.ID, Slug: existing.Slug}) | ||
) | ||
|
||
assertConstraint(t, err, rel.UniqueConstraint, "slug") | ||
} | ||
|
||
// ForeignKeyConstraintOnInsert tests foreign key constraint specifications on insert. | ||
func ForeignKeyConstraintOnInsert(t *testing.T, repo rel.Repository) { | ||
var ( | ||
err = repo.Insert(ctx, &Extra{UserID: 1000}) | ||
) | ||
|
||
assertConstraint(t, err, rel.ForeignKeyConstraint, "user_id") | ||
} | ||
|
||
// ForeignKeyConstraintOnUpdate tests foreign key constraint specifications on update. | ||
func ForeignKeyConstraintOnUpdate(t *testing.T, repo rel.Repository) { | ||
var ( | ||
record = createExtra(repo, "fk-slug") | ||
) | ||
|
||
record.UserID = 1000 | ||
err := repo.Update(ctx, &record) | ||
assertConstraint(t, err, rel.ForeignKeyConstraint, "user_id") | ||
} | ||
|
||
// CheckConstraintOnInsert tests foreign key constraint specifications on insert. | ||
func CheckConstraintOnInsert(t *testing.T, repo rel.Repository) { | ||
var ( | ||
err = repo.Insert(ctx, &Extra{Score: 150}) | ||
) | ||
|
||
assertConstraint(t, err, rel.CheckConstraint, "score") | ||
} | ||
|
||
// CheckConstraintOnUpdate tests foreign key constraint specifications. | ||
func CheckConstraintOnUpdate(t *testing.T, repo rel.Repository) { | ||
var ( | ||
record = createExtra(repo, "check-slug") | ||
) | ||
|
||
// updating | ||
record.Score = 150 | ||
err := repo.Update(ctx, &record) | ||
assertConstraint(t, err, rel.CheckConstraint, "score") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,171 @@ | ||
package specs | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/go-rel/rel" | ||
"github.com/go-rel/rel/where" | ||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
// Delete tests delete specifications. | ||
func Delete(t *testing.T, repo rel.Repository) { | ||
var ( | ||
address = Address{ | ||
Name: "address", | ||
User: User{Name: "user", Age: 100}, | ||
} | ||
) | ||
|
||
repo.MustInsert(ctx, &address) | ||
assert.NotEqual(t, 0, address.ID) | ||
assert.NotEqual(t, 0, address.User.ID) | ||
|
||
assert.Nil(t, repo.Delete(ctx, &address)) | ||
|
||
waitForReplication() | ||
|
||
assert.Equal(t, rel.NotFoundError{}, repo.Find(ctx, &Address{}, where.Eq("id", address.ID))) | ||
// not deleted because cascade disabled | ||
assert.Nil(t, repo.Find(ctx, &User{}, where.Eq("id", address.User.ID))) | ||
} | ||
|
||
// DeleteAll tests delete specifications. | ||
func DeleteAll(t *testing.T, repo rel.Repository) { | ||
var ( | ||
addresses = []Address{ | ||
{Name: "address1"}, | ||
{Name: "address2"}, | ||
} | ||
) | ||
|
||
repo.MustInsertAll(ctx, &addresses) | ||
assert.NotEqual(t, 0, addresses[0].ID) | ||
assert.NotEqual(t, 0, addresses[1].ID) | ||
|
||
assert.Nil(t, repo.DeleteAll(ctx, &addresses)) | ||
|
||
waitForReplication() | ||
assert.Zero(t, repo.MustCount(ctx, "addresses", where.In("id", addresses[0].ID, addresses[1].ID))) | ||
} | ||
|
||
// DeleteBelongsTo tests delete specifications. | ||
func DeleteBelongsTo(t *testing.T, repo rel.Repository) { | ||
var ( | ||
address = Address{ | ||
Name: "address", | ||
User: User{Name: "user", Age: 100}, | ||
} | ||
) | ||
|
||
repo.MustInsert(ctx, &address) | ||
assert.NotEqual(t, 0, address.ID) | ||
assert.NotEqual(t, 0, address.User.ID) | ||
|
||
assert.Nil(t, repo.Delete(ctx, &address, rel.Cascade(true))) | ||
|
||
waitForReplication() | ||
|
||
assert.Equal(t, rel.NotFoundError{}, repo.Find(ctx, &Address{}, where.Eq("id", address.ID))) | ||
assert.Equal(t, rel.NotFoundError{}, repo.Find(ctx, &User{}, where.Eq("id", address.User.ID))) | ||
} | ||
|
||
// DeleteHasOne tests delete specifications. | ||
func DeleteHasOne(t *testing.T, repo rel.Repository) { | ||
var ( | ||
user = User{ | ||
Name: "user", | ||
Age: 100, | ||
PrimaryAddress: &Address{Name: "primary address"}, | ||
} | ||
) | ||
|
||
repo.MustInsert(ctx, &user) | ||
assert.NotEqual(t, 0, user.ID) | ||
assert.NotEqual(t, 0, user.PrimaryAddress.ID) | ||
|
||
assert.Nil(t, repo.Delete(ctx, &user, rel.Cascade(true))) | ||
|
||
waitForReplication() | ||
|
||
assert.Equal(t, rel.NotFoundError{}, repo.Find(ctx, &User{}, where.Eq("id", user.ID))) | ||
assert.Equal(t, rel.NotFoundError{}, repo.Find(ctx, &Address{}, where.Eq("id", user.PrimaryAddress.ID))) | ||
} | ||
|
||
// DeleteHasMany tests delete specifications. | ||
func DeleteHasMany(t *testing.T, repo rel.Repository) { | ||
tests := []struct { | ||
name string | ||
user User | ||
}{ | ||
{ | ||
name: "with empty has many", | ||
user: User{ | ||
Name: "user", | ||
Age: 100, | ||
Addresses: []Address{}, | ||
}, | ||
}, | ||
{ | ||
name: "with non-empty has many", | ||
user: User{ | ||
Name: "user", | ||
Age: 100, | ||
Addresses: []Address{ | ||
{Name: "address 1"}, | ||
{Name: "address 2"}, | ||
}, | ||
}, | ||
}, | ||
} | ||
|
||
for _, tt := range tests { | ||
t.Run(tt.name, func(t *testing.T) { | ||
repo.MustInsert(ctx, &tt.user) | ||
assert.NotEqual(t, 0, tt.user.ID) | ||
for _, addr := range tt.user.Addresses { | ||
assert.NotEqual(t, 0, addr.ID) | ||
} | ||
|
||
assert.Nil(t, repo.Delete(ctx, &tt.user, rel.Cascade(true))) | ||
|
||
waitForReplication() | ||
|
||
assert.Equal(t, rel.NotFoundError{}, repo.Find(ctx, &User{}, where.Eq("id", tt.user.ID))) | ||
for _, addr := range tt.user.Addresses { | ||
assert.Equal(t, rel.NotFoundError{}, repo.Find(ctx, &Address{}, where.Eq("id", addr.ID))) | ||
} | ||
}) | ||
} | ||
} | ||
|
||
// DeleteAny tests delete all specifications. | ||
func DeleteAny(t *testing.T, repo rel.Repository) { | ||
repo.MustInsert(ctx, &User{Name: "delete", Age: 100}) | ||
repo.MustInsert(ctx, &User{Name: "delete", Age: 100}) | ||
repo.MustInsert(ctx, &User{Name: "other delete", Age: 110}) | ||
|
||
waitForReplication() | ||
|
||
tests := []rel.Query{ | ||
rel.From("users").Where(where.Eq("name", "delete")), | ||
rel.From("users").Where(where.Eq("name", "other delete"), where.Gt("age", 100)), | ||
} | ||
|
||
for _, query := range tests { | ||
var result []User | ||
t.Run("DeleteAny", func(t *testing.T) { | ||
assert.Nil(t, repo.FindAll(ctx, &result, query)) | ||
assert.NotEqual(t, 0, len(result)) | ||
|
||
deletedCount, err := repo.DeleteAny(ctx, query) | ||
assert.Nil(t, err) | ||
assert.NotZero(t, deletedCount) | ||
|
||
waitForReplication() | ||
|
||
assert.Nil(t, repo.FindAll(ctx, &result, query)) | ||
assert.Zero(t, len(result)) | ||
}) | ||
} | ||
} |
Oops, something went wrong.