good morning!!!!

Skip to content
Snippets Groups Projects
mongo_test.go 15.8 KiB
Newer Older
// Copyright (c) 2012-present The upper.io/db authors. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

José Carlos Nieto's avatar
José Carlos Nieto committed
	"github.com/stretchr/testify/suite"
José Carlos Nieto's avatar
José Carlos Nieto committed
	db "upper.io/db.v3"
	"upper.io/db.v3/internal/testsuite"
type artistType struct {
	ID   bson.ObjectId `bson:"_id,omitempty"`
	Name string        `bson:"name"`
}

// Structure for testing conversions and datatypes.
type testValuesStruct struct {
	Uint   uint   `bson:"_uint"`
	Uint8  uint8  `bson:"_uint8"`
	Uint16 uint16 `bson:"_uint16"`
	Uint32 uint32 `bson:"_uint32"`
	Uint64 uint64 `bson:"_uint64"`

	Int   int   `bson:"_int"`
	Int8  int8  `bson:"_int8"`
	Int16 int16 `bson:"_int16"`
	Int32 int32 `bson:"_int32"`
	Int64 int64 `bson:"_int64"`

	Float32 float32 `bson:"_float32"`
	Float64 float64 `bson:"_float64"`

	Bool   bool   `bson:"_bool"`
	String string `bson:"_string"`

	Date  time.Time     `bson:"_date"`
	DateN *time.Time    `bson:"_nildate"`
	DateP *time.Time    `bson:"_ptrdate"`
	Time  time.Duration `bson:"_time"`
var testValues testValuesStruct

func init() {
	t := time.Date(2012, 7, 28, 1, 2, 3, 0, time.Local)

	testValues = testValuesStruct{
		1, 1, 1, 1, 1,
		-1, -1, -1, -1, -1,
		1.337, 1.337,
		true,
		"Hello world!",
		t,
		nil,
		&t,
		time.Second * time.Duration(7331),
	}
José Carlos Nieto's avatar
José Carlos Nieto committed
type AdapterTests struct {
	testsuite.Suite
}

func (s *AdapterTests) SetupSuite() {
	s.Helper = &Helper{}
}

func (s *AdapterTests) TestOpenWithWrongData() {
	var rightSettings, wrongSettings ConnectionURL

	// Attempt to open with safe settings.
	rightSettings = ConnectionURL{
		Database: settings.Database,
		Host:     settings.Host,
		User:     settings.User,
		Password: settings.Password,
	}

	// Attempt to open an empty database.
José Carlos Nieto's avatar
José Carlos Nieto committed
	_, err = Open(rightSettings)
	s.NoError(err)

	// Attempt to open with wrong password.
	wrongSettings = ConnectionURL{
		Database: settings.Database,
		Host:     settings.Host,
		User:     settings.User,
José Carlos Nieto's avatar
José Carlos Nieto committed
	_, err = Open(wrongSettings)
	s.Error(err)

	// Attempt to open with wrong database.
	wrongSettings = ConnectionURL{
		Database: "fail",
		Host:     settings.Host,
		User:     settings.User,
		Password: settings.Password,
José Carlos Nieto's avatar
José Carlos Nieto committed
	_, err = Open(wrongSettings)
	s.Error(err)

	// Attempt to open with wrong username.
	wrongSettings = ConnectionURL{
		Database: settings.Database,
		Host:     settings.Host,
		Password: settings.Password,
José Carlos Nieto's avatar
José Carlos Nieto committed
	_, err = Open(wrongSettings)
	s.Error(err)
José Carlos Nieto's avatar
José Carlos Nieto committed
func (s *AdapterTests) TestTruncate() {
	sess, err := Open(settings)
José Carlos Nieto's avatar
José Carlos Nieto committed
	s.NoError(err)
	// We should close the database when it's no longer in use.
	defer sess.Close()
	// Getting a list of all collections in this database.
	collections, err := sess.Collections()
José Carlos Nieto's avatar
José Carlos Nieto committed
	s.NoError(err)
	for _, name := range collections {
		col := sess.Collection(name)
		// The collection may ot may not exists.
		exists := col.Exists()

		if exists == true {
			// Truncating the structure, if exists.
			err = col.Truncate()
José Carlos Nieto's avatar
José Carlos Nieto committed
			s.NoError(err)
José Carlos Nieto's avatar
José Carlos Nieto committed
func (s *AdapterTests) TestInsert() {
	sess, err := Open(settings)
José Carlos Nieto's avatar
José Carlos Nieto committed
	s.NoError(err)
	// We should close the database when it's no longer in use.
	defer sess.Close()

	// Getting a pointer to the "artist" collection.
	artist := sess.Collection("artist")
José Carlos Nieto's avatar
José Carlos Nieto committed
	_ = artist.Truncate()
	// Inserting a map.
José Carlos Nieto's avatar
José Carlos Nieto committed
	id, err := artist.Insert(map[string]string{
José Carlos Nieto's avatar
José Carlos Nieto committed
	s.NoError(err)
	s.NotZero(id)
José Carlos Nieto's avatar
José Carlos Nieto committed
	_, ok := id.(bson.ObjectId)
	s.True(ok)
José Carlos Nieto's avatar
José Carlos Nieto committed
	s.True(id.(bson.ObjectId).Valid())
	// Inserting a struct.
	id, err = artist.Insert(struct {
José Carlos Nieto's avatar
José Carlos Nieto committed
	s.NoError(err)
	s.NotZero(id)
José Carlos Nieto's avatar
José Carlos Nieto committed
	_, ok = id.(bson.ObjectId)
	s.True(ok)
	s.True(id.(bson.ObjectId).Valid())
	// Inserting a struct (using tags to specify the field name).
	id, err = artist.Insert(struct {
		ArtistName string `bson:"name"`
	}{
		"Slash",
	})
José Carlos Nieto's avatar
José Carlos Nieto committed
	s.NoError(err)
	s.NotNil(id)
José Carlos Nieto's avatar
José Carlos Nieto committed
	_, ok = id.(bson.ObjectId)
	s.True(ok)
	s.True(id.(bson.ObjectId).Valid())
	// Inserting a pointer to a struct
	id, err = artist.Insert(&struct {
Paul Xue's avatar
Paul Xue committed
		ArtistName string `bson:"name"`
	}{
		"Metallica",
	})
José Carlos Nieto's avatar
José Carlos Nieto committed
	s.NoError(err)
	s.NotZero(id)
José Carlos Nieto's avatar
José Carlos Nieto committed
	_, ok = id.(bson.ObjectId)
	s.True(ok)
	s.True(id.(bson.ObjectId).Valid())
	// Inserting a pointer to a map
	id, err = artist.Insert(&map[string]string{
Paul Xue's avatar
Paul Xue committed
		"name": "Freddie",
	})
José Carlos Nieto's avatar
José Carlos Nieto committed
	s.NoError(err)
	s.NotZero(id)
José Carlos Nieto's avatar
José Carlos Nieto committed
	_, ok = id.(bson.ObjectId)
	s.True(ok)
	s.True(id.(bson.ObjectId).Valid())
Paul Xue's avatar
Paul Xue committed
	// Counting elements, must be exactly 6 elements.
José Carlos Nieto's avatar
José Carlos Nieto committed
	total, err := artist.Find().Count()
	s.NoError(err)
	s.Equal(uint64(5), total)
José Carlos Nieto's avatar
José Carlos Nieto committed
func (s *AdapterTests) TestGetNonExistentRow_Issue426() {
	// Opening database.
	sess, err := Open(settings)
José Carlos Nieto's avatar
José Carlos Nieto committed
	s.NoError(err)

	defer sess.Close()

	artist := sess.Collection("artist")

	var one artistType
	err = artist.Find(db.Cond{"name": "nothing"}).One(&one)

José Carlos Nieto's avatar
José Carlos Nieto committed
	s.NotZero(err)
	s.Equal(db.ErrNoMoreRows, err)

	var all []artistType
	err = artist.Find(db.Cond{"name": "nothing"}).All(&all)

José Carlos Nieto's avatar
José Carlos Nieto committed
	s.Zero(err, "All should not return mgo.ErrNotFound")
	s.Equal(0, len(all))
José Carlos Nieto's avatar
José Carlos Nieto committed
func (s *AdapterTests) TestResultCount() {
	var err error
	sess, err := Open(settings)
José Carlos Nieto's avatar
José Carlos Nieto committed
	s.NoError(err)
	defer sess.Close()

	// We should close the database when it's no longer in use.
	artist := sess.Collection("artist")
	// Counting all the matching rows.
	total, err := res.Count()
José Carlos Nieto's avatar
José Carlos Nieto committed
	s.NoError(err)
	s.NotZero(total)
José Carlos Nieto's avatar
José Carlos Nieto committed
func (s *AdapterTests) TestGroup() {
José Carlos Nieto's avatar
José Carlos Nieto committed
	sess, err := Open(settings)
	s.NoError(err)
	type statsT struct {
		Numeric int `db:"numeric" bson:"numeric"`
		Value   int `db:"value" bson:"value"`
	}

	defer sess.Close()

	stats = sess.Collection("statsTest")

	// Adding row append.
	for i := 0; i < 1000; i++ {
		numeric, value := rand.Intn(10), rand.Intn(100)
José Carlos Nieto's avatar
José Carlos Nieto committed
		_, err = stats.Insert(statsT{numeric, value})
		s.NoError(err)
	// db.statsTest.group({key: {numeric: true}, initial: {sum: 0}, reduce: function(doc, prev) { prev.sum += 1}});

	// Testing GROUP BY
	res := stats.Find().Group(bson.M{
		"key":     bson.M{"numeric": true},
		"initial": bson.M{"sum": 0},
		"reduce":  `function(doc, prev) { prev.sum += 1}`,
	})

	var results []map[string]interface{}

	err = res.All(&results)
José Carlos Nieto's avatar
José Carlos Nieto committed
	s.Equal(db.ErrUnsupported, err)
José Carlos Nieto's avatar
José Carlos Nieto committed
func (s *AdapterTests) TestResultNonExistentCount() {
	sess, err := Open(settings)
José Carlos Nieto's avatar
José Carlos Nieto committed
	s.NoError(err)
	total, err := sess.Collection("notartist").Find().Count()
José Carlos Nieto's avatar
José Carlos Nieto committed
	s.NoError(err)
	s.Zero(total)
José Carlos Nieto's avatar
José Carlos Nieto committed
func (s *AdapterTests) TestResultFetch() {
	sess, err := Open(settings)
José Carlos Nieto's avatar
José Carlos Nieto committed
	s.NoError(err)
	// We should close the database when it's no longer in use.
	defer sess.Close()
	artist := sess.Collection("artist")
José Carlos Nieto's avatar
José Carlos Nieto committed
	res := artist.Find()
	rowM := map[string]interface{}{}
	for res.Next(&rowM) {
José Carlos Nieto's avatar
José Carlos Nieto committed
		s.NotZero(rowM["_id"])
José Carlos Nieto's avatar
José Carlos Nieto committed
		_, ok := rowM["_id"].(bson.ObjectId)
		s.True(ok)

		s.True(rowM["_id"].(bson.ObjectId).Valid())

		name, ok := rowM["name"].(string)
		s.True(ok)
		s.NotZero(name)
José Carlos Nieto's avatar
José Carlos Nieto committed
	err = res.Close()
	s.NoError(err)
	rowS := struct {
		ID   bson.ObjectId `bson:"_id"`
	for res.Next(&rowS) {
José Carlos Nieto's avatar
José Carlos Nieto committed
		s.True(rowS.ID.Valid())
		s.NotZero(rowS.Name)
José Carlos Nieto's avatar
José Carlos Nieto committed
	err = res.Close()
	s.NoError(err)
	rowT := struct {
		Value1 bson.ObjectId `bson:"_id"`
		Value2 string        `bson:"name"`
	}{}
	for res.Next(&rowT) {
José Carlos Nieto's avatar
José Carlos Nieto committed
		s.True(rowT.Value1.Valid())
		s.NotZero(rowT.Value2)
José Carlos Nieto's avatar
José Carlos Nieto committed
	err = res.Close()
	s.NoError(err)
	// Testing Result.All() with a slice of maps.
	allRowsM := []map[string]interface{}{}
	err = res.All(&allRowsM)
José Carlos Nieto's avatar
José Carlos Nieto committed
	s.NoError(err)
	for _, singleRowM := range allRowsM {
José Carlos Nieto's avatar
José Carlos Nieto committed
		s.NotZero(singleRowM["_id"])
	// Testing Result.All() with a slice of structs.
	allRowsS := []struct {
		ID   bson.ObjectId `bson:"_id"`
	err = res.All(&allRowsS)
José Carlos Nieto's avatar
José Carlos Nieto committed
	s.NoError(err)
	for _, singleRowS := range allRowsS {
José Carlos Nieto's avatar
José Carlos Nieto committed
		s.True(singleRowS.ID.Valid())
	// Testing Result.All() with a slice of tagged structs.
	allRowsT := []struct {
		Value1 bson.ObjectId `bson:"_id"`
		Value2 string        `bson:"name"`
	}{}
	err = res.All(&allRowsT)
José Carlos Nieto's avatar
José Carlos Nieto committed
	s.NoError(err)
	for _, singleRowT := range allRowsT {
José Carlos Nieto's avatar
José Carlos Nieto committed
		s.True(singleRowT.Value1.Valid())
José Carlos Nieto's avatar
José Carlos Nieto committed
	}
José Carlos Nieto's avatar
José Carlos Nieto committed
func (s *AdapterTests) TestUpdate() {
	sess, err := Open(settings)
José Carlos Nieto's avatar
José Carlos Nieto committed
	s.NoError(err)
José Carlos Nieto's avatar
José Carlos Nieto committed

	// We should close the database when it's no longer in use.
José Carlos Nieto's avatar
José Carlos Nieto committed
	defer sess.Close()

	// Getting a pointer to the "artist" collection.
	artist := sess.Collection("artist")
José Carlos Nieto's avatar
José Carlos Nieto committed

		ID   bson.ObjectId `bson:"_id"`
José Carlos Nieto's avatar
José Carlos Nieto committed

	res := artist.Find(db.Cond{"_id": db.NotEq(nil)}).Limit(1)
José Carlos Nieto's avatar
José Carlos Nieto committed
	s.NoError(err)
	rowM := map[string]interface{}{
		"name": strings.ToUpper(value.Name),
	}
	err = res.Update(rowM)
José Carlos Nieto's avatar
José Carlos Nieto committed
	s.NoError(err)
José Carlos Nieto's avatar
José Carlos Nieto committed
	s.NoError(err)
José Carlos Nieto's avatar
José Carlos Nieto committed
	s.Equal(value.Name, rowM["name"])
	rowS := struct {
		Name string
	}{strings.ToLower(value.Name)}
	err = res.Update(rowS)
José Carlos Nieto's avatar
José Carlos Nieto committed
	s.NoError(err)
José Carlos Nieto's avatar
José Carlos Nieto committed
	s.NoError(err)
José Carlos Nieto's avatar
José Carlos Nieto committed
	s.Equal(value.Name, rowS.Name)
	// Updating with a tagged struct
	rowT := struct {
		Value1 string `bson:"name"`
	}{strings.Replace(value.Name, "z", "Z", -1)}
	err = res.Update(rowT)
José Carlos Nieto's avatar
José Carlos Nieto committed
	s.NoError(err)
José Carlos Nieto's avatar
José Carlos Nieto committed
	s.NoError(err)
José Carlos Nieto's avatar
José Carlos Nieto committed
	s.Equal(value.Name, rowT.Value1)
José Carlos Nieto's avatar
José Carlos Nieto committed
func (s *AdapterTests) TestOperators() {
Carlos Nieto's avatar
Carlos Nieto committed
	// Opening database.
	sess, err := Open(settings)
José Carlos Nieto's avatar
José Carlos Nieto committed
	s.NoError(err)
Carlos Nieto's avatar
Carlos Nieto committed

	// We should close the database when it's no longer in use.
	defer sess.Close()

	// Getting a pointer to the "artist" collection.
	artist := sess.Collection("artist")
	rowS := struct {
		ID   uint64
Carlos Nieto's avatar
Carlos Nieto committed
		Name string
	}{}

José Carlos Nieto's avatar
José Carlos Nieto committed
	res := artist.Find(db.Cond{"_id": db.NotIn([]int{0, -1})})
José Carlos Nieto's avatar
José Carlos Nieto committed
	err = res.One(&rowS)
	s.NoError(err)
José Carlos Nieto's avatar
José Carlos Nieto committed
	err = res.Close()
	s.NoError(err)
José Carlos Nieto's avatar
José Carlos Nieto committed
func (s *AdapterTests) TestDelete() {
	sess, err := Open(settings)
José Carlos Nieto's avatar
José Carlos Nieto committed
	s.NoError(err)
	// We should close the database when it's no longer in use.
	defer sess.Close()

	// Getting a pointer to the "artist" collection.
	artist := sess.Collection("artist")
	res := artist.Find(db.Cond{"_id": db.NotEq(nil)}).Limit(1)
		ID bson.ObjectId `bson:"_id"`
José Carlos Nieto's avatar
José Carlos Nieto committed
	s.NoError(err)
	res = artist.Find(db.Cond{"_id": db.Eq(first.ID)})
	err = res.Delete()
José Carlos Nieto's avatar
José Carlos Nieto committed
	s.NoError(err)
José Carlos Nieto's avatar
José Carlos Nieto committed
func (s *AdapterTests) TestDataTypes() {
	sess, err := Open(settings)
José Carlos Nieto's avatar
José Carlos Nieto committed
	s.NoError(err)
	// We should close the database when it's no longer in use.
	defer sess.Close()

	// Getting a pointer to the "data_types" collection.
	dataTypes := sess.Collection("data_types")
	// Inserting our test subject.
	id, err := dataTypes.Insert(testValues)
José Carlos Nieto's avatar
José Carlos Nieto committed
	s.NoError(err)
	s.NotZero(id)
	// Trying to get the same subject we added.
José Carlos Nieto's avatar
José Carlos Nieto committed
	res := dataTypes.Find(db.Cond{"_id": db.Eq(id)})
José Carlos Nieto's avatar
José Carlos Nieto committed
	s.NoError(err)
	s.NotZero(exists)
	// Trying to dump the subject into an empty structure of the same type.
	var item testValuesStruct
	res.One(&item)
	// The original value and the test subject must match.
José Carlos Nieto's avatar
José Carlos Nieto committed
	s.Equal(testValues, item)
José Carlos Nieto's avatar
José Carlos Nieto committed
func (s *AdapterTests) TestPaginator() {
	// Opening database.
	sess, err := Open(settings)
José Carlos Nieto's avatar
José Carlos Nieto committed
	s.NoError(err)

	// We should close the database when it's no longer in use.
	defer sess.Close()

	// Getting a pointer to the "artist" collection.
	artist := sess.Collection("artist")

	err = artist.Truncate()
José Carlos Nieto's avatar
José Carlos Nieto committed
	s.NoError(err)

	for i := 0; i < 999; i++ {
		_, err = artist.Insert(artistType{
			Name: fmt.Sprintf("artist-%d", i),
		})
José Carlos Nieto's avatar
José Carlos Nieto committed
		s.NoError(err)
	}

	q := sess.Collection("artist").Find().Paginate(15)
	paginator := q.Paginate(13)

	var zerothPage []artistType
	err = paginator.Page(0).All(&zerothPage)
José Carlos Nieto's avatar
José Carlos Nieto committed
	s.NoError(err)
	s.Equal(13, len(zerothPage))

	var secondPage []artistType
	err = paginator.Page(2).All(&secondPage)
José Carlos Nieto's avatar
José Carlos Nieto committed
	s.NoError(err)
	s.Equal(13, len(secondPage))

	tp, err := paginator.TotalPages()
José Carlos Nieto's avatar
José Carlos Nieto committed
	s.NoError(err)
	s.NotZero(tp)
	s.Equal(uint(77), tp)
José Carlos Nieto's avatar
José Carlos Nieto committed
	ti, err := paginator.TotalEntries()
José Carlos Nieto's avatar
José Carlos Nieto committed
	s.NoError(err)
	s.NotZero(ti)
	s.Equal(uint64(999), ti)

	var seventySixthPage []artistType
	err = paginator.Page(76).All(&seventySixthPage)
José Carlos Nieto's avatar
José Carlos Nieto committed
	s.NoError(err)
	s.Equal(11, len(seventySixthPage))

	var seventySeventhPage []artistType
	err = paginator.Page(77).All(&seventySeventhPage)
José Carlos Nieto's avatar
José Carlos Nieto committed
	s.NoError(err)
	s.Equal(0, len(seventySeventhPage))

	var hundredthPage []artistType
	err = paginator.Page(100).All(&hundredthPage)
José Carlos Nieto's avatar
José Carlos Nieto committed
	s.NoError(err)
	s.Equal(0, len(hundredthPage))
José Carlos Nieto's avatar
José Carlos Nieto committed
	for i := uint(0); i < tp; i++ {
		current := paginator.Page(i)

		var items []artistType
		err := current.All(&items)
José Carlos Nieto's avatar
José Carlos Nieto committed
		s.NoError(err)
		if len(items) < 1 {
			break
		}
		for j := 0; j < len(items); j++ {
José Carlos Nieto's avatar
José Carlos Nieto committed
			s.Equal(fmt.Sprintf("artist-%d", int64(13*int(i)+j)), items[j].Name)
		}
	}

	paginator = paginator.Cursor("_id")
	{
		current := paginator.Page(0)
		for i := 0; ; i++ {
			var items []artistType
			err := current.All(&items)
José Carlos Nieto's avatar
José Carlos Nieto committed
			s.NoError(err)

			if len(items) < 1 {
				break
			}

			for j := 0; j < len(items); j++ {
José Carlos Nieto's avatar
José Carlos Nieto committed
				s.Equal(fmt.Sprintf("artist-%d", int64(13*int(i)+j)), items[j].Name)
			}
			current = current.NextPage(items[len(items)-1].ID)
		}
	}

	{
		log.Printf("Page 76")
		current := paginator.Page(76)
		for i := 76; ; i-- {
			var items []artistType

			err := current.All(&items)
José Carlos Nieto's avatar
José Carlos Nieto committed
			s.NoError(err)

			if len(items) < 1 {
José Carlos Nieto's avatar
José Carlos Nieto committed
				s.Equal(0, len(items))
				break
			}
			for j := 0; j < len(items); j++ {
José Carlos Nieto's avatar
José Carlos Nieto committed
				s.Equal(fmt.Sprintf("artist-%d", 13*int(i)+j), items[j].Name)
			}

			current = current.PrevPage(items[0].ID)
		}
	}

	{
		resultPaginator := sess.Collection("artist").Find().Paginate(15)

		count, err := resultPaginator.TotalPages()
José Carlos Nieto's avatar
José Carlos Nieto committed
		s.Equal(uint(67), count)
		s.NoError(err)

		var items []artistType
		err = resultPaginator.Page(5).All(&items)
José Carlos Nieto's avatar
José Carlos Nieto committed
		s.NoError(err)

		for j := 0; j < len(items); j++ {
José Carlos Nieto's avatar
José Carlos Nieto committed
			s.Equal(fmt.Sprintf("artist-%d", 15*5+j), items[j].Name)
		}

		resultPaginator = resultPaginator.Cursor("_id").Page(0)
		for i := 0; ; i++ {
			var items []artistType

			err = resultPaginator.All(&items)
José Carlos Nieto's avatar
José Carlos Nieto committed
			s.NoError(err)

			if len(items) < 1 {
				break
			}

			for j := 0; j < len(items); j++ {
José Carlos Nieto's avatar
José Carlos Nieto committed
				s.Equal(fmt.Sprintf("artist-%d", 15*i+j), items[j].Name)
			}
			resultPaginator = resultPaginator.NextPage(items[len(items)-1].ID)
		}

		resultPaginator = resultPaginator.Cursor("_id").Page(66)
		for i := 66; ; i-- {
			var items []artistType

			err = resultPaginator.All(&items)
José Carlos Nieto's avatar
José Carlos Nieto committed
			s.NoError(err)

			if len(items) < 1 {
				break
			}

			for j := 0; j < len(items); j++ {
José Carlos Nieto's avatar
José Carlos Nieto committed
				s.Equal(fmt.Sprintf("artist-%d", 15*i+j), items[j].Name)
			}
			resultPaginator = resultPaginator.PrevPage(items[0].ID)
		}
	}
}
José Carlos Nieto's avatar
José Carlos Nieto committed

func TestAdapter(t *testing.T) {
	suite.Run(t, &AdapterTests{})
}