// Generated by tmpl
// https://github.com/benbjohnson/tmpl
//
// DO NOT EDIT!
// Source: array_cursor_test.gen.go.tmpl

package reads

import (
	"context"
	"testing"
	"time"

	"github.com/google/go-cmp/cmp"
	"github.com/influxdata/flux/interval"
	"github.com/influxdata/flux/values"
	"github.com/influxdata/influxdb/storage/reads/datatypes"
	"github.com/influxdata/influxdb/tsdb/cursors"
)

var cmpOptions = cmp.AllowUnexported(interval.Window{})

type MockFloatArrayCursor struct {
	CloseFunc func()
	ErrFunc   func() error
	StatsFunc func() cursors.CursorStats
	NextFunc  func() *cursors.FloatArray
}

func (c *MockFloatArrayCursor) Close()                     { c.CloseFunc() }
func (c *MockFloatArrayCursor) Err() error                 { return c.ErrFunc() }
func (c *MockFloatArrayCursor) Stats() cursors.CursorStats { return c.StatsFunc() }
func (c *MockFloatArrayCursor) Next() *cursors.FloatArray  { return c.NextFunc() }

func TestNewAggregateArrayCursor_Float(t *testing.T) {

	t.Run("Count", func(t *testing.T) {
		want := &floatWindowCountArrayCursor{
			FloatArrayCursor: &MockFloatArrayCursor{},
			res:              cursors.NewIntegerArrayLen(1),
			tmp:              &cursors.FloatArray{},
		}

		agg := []*datatypes.Aggregate{
			&datatypes.Aggregate{Type: datatypes.Aggregate_AggregateTypeCount},
		}

		got, _ := newAggregateArrayCursor(context.Background(), agg, &MockFloatArrayCursor{})

		if diff := cmp.Diff(got, want, cmp.AllowUnexported(floatWindowCountArrayCursor{}), cmpOptions); diff != "" {
			t.Fatalf("did not get expected cursor; -got/+want:\n%v", diff)
		}
	})

	t.Run("Sum", func(t *testing.T) {
		want := &floatWindowSumArrayCursor{
			FloatArrayCursor: &MockFloatArrayCursor{},
			res:              cursors.NewFloatArrayLen(1),
			tmp:              &cursors.FloatArray{},
		}

		agg := []*datatypes.Aggregate{
			&datatypes.Aggregate{Type: datatypes.Aggregate_AggregateTypeSum},
		}

		got, _ := newAggregateArrayCursor(context.Background(), agg, &MockFloatArrayCursor{})

		if diff := cmp.Diff(got, want, cmp.AllowUnexported(floatWindowSumArrayCursor{}), cmpOptions); diff != "" {
			t.Fatalf("did not get expected cursor; -got/+want:\n%v", diff)
		}
	})

	t.Run("Min", func(t *testing.T) {
		want := &floatWindowMinArrayCursor{
			FloatArrayCursor: &MockFloatArrayCursor{},
			res:              cursors.NewFloatArrayLen(1),
			tmp:              &cursors.FloatArray{},
		}

		agg := []*datatypes.Aggregate{
			&datatypes.Aggregate{Type: datatypes.Aggregate_AggregateTypeMin},
		}

		got, _ := newAggregateArrayCursor(context.Background(), agg, &MockFloatArrayCursor{})

		if diff := cmp.Diff(got, want, cmp.AllowUnexported(floatWindowMinArrayCursor{}), cmpOptions); diff != "" {
			t.Fatalf("did not get expected cursor; -got/+want:\n%v", diff)
		}
	})

	t.Run("Max", func(t *testing.T) {
		want := &floatWindowMaxArrayCursor{
			FloatArrayCursor: &MockFloatArrayCursor{},
			res:              cursors.NewFloatArrayLen(1),
			tmp:              &cursors.FloatArray{},
		}

		agg := []*datatypes.Aggregate{
			&datatypes.Aggregate{Type: datatypes.Aggregate_AggregateTypeMax},
		}

		got, _ := newAggregateArrayCursor(context.Background(), agg, &MockFloatArrayCursor{})

		if diff := cmp.Diff(got, want, cmp.AllowUnexported(floatWindowMaxArrayCursor{}), cmpOptions); diff != "" {
			t.Fatalf("did not get expected cursor; -got/+want:\n%v", diff)
		}
	})

	t.Run("Mean", func(t *testing.T) {
		want := &floatWindowMeanArrayCursor{
			FloatArrayCursor: &MockFloatArrayCursor{},
			res:              cursors.NewFloatArrayLen(1),
			tmp:              &cursors.FloatArray{},
		}

		agg := []*datatypes.Aggregate{
			&datatypes.Aggregate{Type: datatypes.Aggregate_AggregateTypeMean},
		}

		got, _ := newAggregateArrayCursor(context.Background(), agg, &MockFloatArrayCursor{})

		if diff := cmp.Diff(got, want, cmp.AllowUnexported(floatWindowMeanArrayCursor{}), cmpOptions); diff != "" {
			t.Fatalf("did not get expected cursor; -got/+want:\n%v", diff)
		}
	})

	t.Run("MeanCount", func(t *testing.T) {
		want := &floatWindowMeanCountArrayCursor{
			FloatArrayCursor: &MockFloatArrayCursor{},
			res:              cursors.NewMeanCountArrayLen(1),
			tmp:              &cursors.FloatArray{},
		}

		agg := []*datatypes.Aggregate{
			&datatypes.Aggregate{Type: datatypes.Aggregate_AggregateTypeMean},
			&datatypes.Aggregate{Type: datatypes.Aggregate_AggregateTypeCount},
		}

		got, _ := newAggregateArrayCursor(context.Background(), agg, &MockFloatArrayCursor{})

		if diff := cmp.Diff(got, want, cmp.AllowUnexported(floatWindowMeanCountArrayCursor{}), cmpOptions); diff != "" {
			t.Fatalf("did not get expected cursor; -got/+want:\n%v", diff)
		}
	})

}

func TestNewWindowAggregateArrayCursorMonths_Float(t *testing.T) {

	t.Run("Count", func(t *testing.T) {
		window, _ := interval.NewWindow(
			values.MakeDuration(int64(time.Hour), 0, false),
			values.MakeDuration(int64(time.Hour), 0, false),
			values.MakeDuration(0, 0, false),
		)

		want := &floatWindowCountArrayCursor{
			FloatArrayCursor: &MockFloatArrayCursor{},
			res:              cursors.NewIntegerArrayLen(MaxPointsPerBlock),
			tmp:              &cursors.FloatArray{},
			window:           window,
		}

		agg := []*datatypes.Aggregate{
			&datatypes.Aggregate{Type: datatypes.Aggregate_AggregateTypeCount},
		}

		got, _ := NewWindowAggregateArrayCursor(context.Background(), agg, window, &MockFloatArrayCursor{})

		if diff := cmp.Diff(got, want, cmp.AllowUnexported(floatWindowCountArrayCursor{}), cmpOptions); diff != "" {
			t.Fatalf("did not get expected cursor; -got/+want:\n%v", diff)
		}
	})

	t.Run("Sum", func(t *testing.T) {
		window, _ := interval.NewWindow(
			values.MakeDuration(int64(time.Hour), 0, false),
			values.MakeDuration(int64(time.Hour), 0, false),
			values.MakeDuration(0, 0, false),
		)

		want := &floatWindowSumArrayCursor{
			FloatArrayCursor: &MockFloatArrayCursor{},
			res:              cursors.NewFloatArrayLen(MaxPointsPerBlock),
			tmp:              &cursors.FloatArray{},
			window:           window,
		}

		agg := []*datatypes.Aggregate{
			&datatypes.Aggregate{Type: datatypes.Aggregate_AggregateTypeSum},
		}

		got, _ := NewWindowAggregateArrayCursor(context.Background(), agg, window, &MockFloatArrayCursor{})

		if diff := cmp.Diff(got, want, cmp.AllowUnexported(floatWindowSumArrayCursor{}), cmpOptions); diff != "" {
			t.Fatalf("did not get expected cursor; -got/+want:\n%v", diff)
		}
	})

	t.Run("Min", func(t *testing.T) {
		window, _ := interval.NewWindow(
			values.MakeDuration(int64(time.Hour), 0, false),
			values.MakeDuration(int64(time.Hour), 0, false),
			values.MakeDuration(0, 0, false),
		)

		want := &floatWindowMinArrayCursor{
			FloatArrayCursor: &MockFloatArrayCursor{},
			res:              cursors.NewFloatArrayLen(MaxPointsPerBlock),
			tmp:              &cursors.FloatArray{},
			window:           window,
		}

		agg := []*datatypes.Aggregate{
			&datatypes.Aggregate{Type: datatypes.Aggregate_AggregateTypeMin},
		}

		got, _ := NewWindowAggregateArrayCursor(context.Background(), agg, window, &MockFloatArrayCursor{})

		if diff := cmp.Diff(got, want, cmp.AllowUnexported(floatWindowMinArrayCursor{}), cmpOptions); diff != "" {
			t.Fatalf("did not get expected cursor; -got/+want:\n%v", diff)
		}
	})

	t.Run("Max", func(t *testing.T) {
		window, _ := interval.NewWindow(
			values.MakeDuration(int64(time.Hour), 0, false),
			values.MakeDuration(int64(time.Hour), 0, false),
			values.MakeDuration(0, 0, false),
		)

		want := &floatWindowMaxArrayCursor{
			FloatArrayCursor: &MockFloatArrayCursor{},
			res:              cursors.NewFloatArrayLen(MaxPointsPerBlock),
			tmp:              &cursors.FloatArray{},
			window:           window,
		}

		agg := []*datatypes.Aggregate{
			&datatypes.Aggregate{Type: datatypes.Aggregate_AggregateTypeMax},
		}

		got, _ := NewWindowAggregateArrayCursor(context.Background(), agg, window, &MockFloatArrayCursor{})

		if diff := cmp.Diff(got, want, cmp.AllowUnexported(floatWindowMaxArrayCursor{}), cmpOptions); diff != "" {
			t.Fatalf("did not get expected cursor; -got/+want:\n%v", diff)
		}
	})

	t.Run("Mean", func(t *testing.T) {
		window, _ := interval.NewWindow(
			values.MakeDuration(int64(time.Hour), 0, false),
			values.MakeDuration(int64(time.Hour), 0, false),
			values.MakeDuration(0, 0, false),
		)

		want := &floatWindowMeanArrayCursor{
			FloatArrayCursor: &MockFloatArrayCursor{},
			res:              cursors.NewFloatArrayLen(MaxPointsPerBlock),
			tmp:              &cursors.FloatArray{},
			window:           window,
		}

		agg := []*datatypes.Aggregate{
			&datatypes.Aggregate{Type: datatypes.Aggregate_AggregateTypeMean},
		}

		got, _ := NewWindowAggregateArrayCursor(context.Background(), agg, window, &MockFloatArrayCursor{})

		if diff := cmp.Diff(got, want, cmp.AllowUnexported(floatWindowMeanArrayCursor{}), cmpOptions); diff != "" {
			t.Fatalf("did not get expected cursor; -got/+want:\n%v", diff)
		}
	})

	t.Run("MeanCount", func(t *testing.T) {
		window, _ := interval.NewWindow(
			values.MakeDuration(int64(time.Hour), 0, false),
			values.MakeDuration(int64(time.Hour), 0, false),
			values.MakeDuration(0, 0, false),
		)

		want := &floatWindowMeanCountArrayCursor{
			FloatArrayCursor: &MockFloatArrayCursor{},
			res:              cursors.NewMeanCountArrayLen(MaxPointsPerBlock),
			tmp:              &cursors.FloatArray{},
			window:           window,
		}

		agg := []*datatypes.Aggregate{
			&datatypes.Aggregate{Type: datatypes.Aggregate_AggregateTypeMean},
			&datatypes.Aggregate{Type: datatypes.Aggregate_AggregateTypeCount},
		}

		got, _ := NewWindowAggregateArrayCursor(context.Background(), agg, window, &MockFloatArrayCursor{})

		if diff := cmp.Diff(got, want, cmp.AllowUnexported(floatWindowMeanCountArrayCursor{}), cmpOptions); diff != "" {
			t.Fatalf("did not get expected cursor; -got/+want:\n%v", diff)
		}
	})

}

func TestNewWindowAggregateArrayCursor_Float(t *testing.T) {

	t.Run("Count", func(t *testing.T) {
		window, _ := interval.NewWindow(
			values.MakeDuration(0, 1, false),
			values.MakeDuration(0, 1, false),
			values.MakeDuration(0, 0, false),
		)

		want := &floatWindowCountArrayCursor{
			FloatArrayCursor: &MockFloatArrayCursor{},
			res:              cursors.NewIntegerArrayLen(MaxPointsPerBlock),
			tmp:              &cursors.FloatArray{},
			window:           window,
		}

		agg := []*datatypes.Aggregate{
			&datatypes.Aggregate{Type: datatypes.Aggregate_AggregateTypeCount},
		}

		got, _ := NewWindowAggregateArrayCursor(context.Background(), agg, window, &MockFloatArrayCursor{})

		if diff := cmp.Diff(got, want, cmp.AllowUnexported(floatWindowCountArrayCursor{}), cmpOptions); diff != "" {
			t.Fatalf("did not get expected cursor; -got/+want:\n%v", diff)
		}
	})

	t.Run("Sum", func(t *testing.T) {
		window, _ := interval.NewWindow(
			values.MakeDuration(0, 1, false),
			values.MakeDuration(0, 1, false),
			values.MakeDuration(0, 0, false),
		)

		want := &floatWindowSumArrayCursor{
			FloatArrayCursor: &MockFloatArrayCursor{},
			res:              cursors.NewFloatArrayLen(MaxPointsPerBlock),
			tmp:              &cursors.FloatArray{},
			window:           window,
		}

		agg := []*datatypes.Aggregate{
			&datatypes.Aggregate{Type: datatypes.Aggregate_AggregateTypeSum},
		}

		got, _ := NewWindowAggregateArrayCursor(context.Background(), agg, window, &MockFloatArrayCursor{})

		if diff := cmp.Diff(got, want, cmp.AllowUnexported(floatWindowSumArrayCursor{}), cmpOptions); diff != "" {
			t.Fatalf("did not get expected cursor; -got/+want:\n%v", diff)
		}
	})

	t.Run("Min", func(t *testing.T) {
		window, _ := interval.NewWindow(
			values.MakeDuration(0, 1, false),
			values.MakeDuration(0, 1, false),
			values.MakeDuration(0, 0, false),
		)

		want := &floatWindowMinArrayCursor{
			FloatArrayCursor: &MockFloatArrayCursor{},
			res:              cursors.NewFloatArrayLen(MaxPointsPerBlock),
			tmp:              &cursors.FloatArray{},
			window:           window,
		}

		agg := []*datatypes.Aggregate{
			&datatypes.Aggregate{Type: datatypes.Aggregate_AggregateTypeMin},
		}

		got, _ := NewWindowAggregateArrayCursor(context.Background(), agg, window, &MockFloatArrayCursor{})

		if diff := cmp.Diff(got, want, cmp.AllowUnexported(floatWindowMinArrayCursor{}), cmpOptions); diff != "" {
			t.Fatalf("did not get expected cursor; -got/+want:\n%v", diff)
		}
	})

	t.Run("Max", func(t *testing.T) {
		window, _ := interval.NewWindow(
			values.MakeDuration(0, 1, false),
			values.MakeDuration(0, 1, false),
			values.MakeDuration(0, 0, false),
		)

		want := &floatWindowMaxArrayCursor{
			FloatArrayCursor: &MockFloatArrayCursor{},
			res:              cursors.NewFloatArrayLen(MaxPointsPerBlock),
			tmp:              &cursors.FloatArray{},
			window:           window,
		}

		agg := []*datatypes.Aggregate{
			&datatypes.Aggregate{Type: datatypes.Aggregate_AggregateTypeMax},
		}

		got, _ := NewWindowAggregateArrayCursor(context.Background(), agg, window, &MockFloatArrayCursor{})

		if diff := cmp.Diff(got, want, cmp.AllowUnexported(floatWindowMaxArrayCursor{}), cmpOptions); diff != "" {
			t.Fatalf("did not get expected cursor; -got/+want:\n%v", diff)
		}
	})

	t.Run("Mean", func(t *testing.T) {
		window, _ := interval.NewWindow(
			values.MakeDuration(0, 1, false),
			values.MakeDuration(0, 1, false),
			values.MakeDuration(0, 0, false),
		)

		want := &floatWindowMeanArrayCursor{
			FloatArrayCursor: &MockFloatArrayCursor{},
			res:              cursors.NewFloatArrayLen(MaxPointsPerBlock),
			tmp:              &cursors.FloatArray{},
			window:           window,
		}

		agg := []*datatypes.Aggregate{
			&datatypes.Aggregate{Type: datatypes.Aggregate_AggregateTypeMean},
		}

		got, _ := NewWindowAggregateArrayCursor(context.Background(), agg, window, &MockFloatArrayCursor{})

		if diff := cmp.Diff(got, want, cmp.AllowUnexported(floatWindowMeanArrayCursor{}), cmpOptions); diff != "" {
			t.Fatalf("did not get expected cursor; -got/+want:\n%v", diff)
		}
	})

	t.Run("MeanCount", func(t *testing.T) {
		window, _ := interval.NewWindow(
			values.MakeDuration(0, 1, false),
			values.MakeDuration(0, 1, false),
			values.MakeDuration(0, 0, false),
		)

		want := &floatWindowMeanCountArrayCursor{
			FloatArrayCursor: &MockFloatArrayCursor{},
			res:              cursors.NewMeanCountArrayLen(MaxPointsPerBlock),
			tmp:              &cursors.FloatArray{},
			window:           window,
		}

		agg := []*datatypes.Aggregate{
			&datatypes.Aggregate{Type: datatypes.Aggregate_AggregateTypeMean},
			&datatypes.Aggregate{Type: datatypes.Aggregate_AggregateTypeCount},
		}

		got, _ := NewWindowAggregateArrayCursor(context.Background(), agg, window, &MockFloatArrayCursor{})

		if diff := cmp.Diff(got, want, cmp.AllowUnexported(floatWindowMeanCountArrayCursor{}), cmpOptions); diff != "" {
			t.Fatalf("did not get expected cursor; -got/+want:\n%v", diff)
		}
	})

}

type MockIntegerArrayCursor struct {
	CloseFunc func()
	ErrFunc   func() error
	StatsFunc func() cursors.CursorStats
	NextFunc  func() *cursors.IntegerArray
}

func (c *MockIntegerArrayCursor) Close()                      { c.CloseFunc() }
func (c *MockIntegerArrayCursor) Err() error                  { return c.ErrFunc() }
func (c *MockIntegerArrayCursor) Stats() cursors.CursorStats  { return c.StatsFunc() }
func (c *MockIntegerArrayCursor) Next() *cursors.IntegerArray { return c.NextFunc() }

func TestNewAggregateArrayCursor_Integer(t *testing.T) {

	t.Run("Count", func(t *testing.T) {
		want := &integerWindowCountArrayCursor{
			IntegerArrayCursor: &MockIntegerArrayCursor{},
			res:                cursors.NewIntegerArrayLen(1),
			tmp:                &cursors.IntegerArray{},
		}

		agg := []*datatypes.Aggregate{
			&datatypes.Aggregate{Type: datatypes.Aggregate_AggregateTypeCount},
		}

		got, _ := newAggregateArrayCursor(context.Background(), agg, &MockIntegerArrayCursor{})

		if diff := cmp.Diff(got, want, cmp.AllowUnexported(integerWindowCountArrayCursor{}), cmpOptions); diff != "" {
			t.Fatalf("did not get expected cursor; -got/+want:\n%v", diff)
		}
	})

	t.Run("Sum", func(t *testing.T) {
		want := &integerWindowSumArrayCursor{
			IntegerArrayCursor: &MockIntegerArrayCursor{},
			res:                cursors.NewIntegerArrayLen(1),
			tmp:                &cursors.IntegerArray{},
		}

		agg := []*datatypes.Aggregate{
			&datatypes.Aggregate{Type: datatypes.Aggregate_AggregateTypeSum},
		}

		got, _ := newAggregateArrayCursor(context.Background(), agg, &MockIntegerArrayCursor{})

		if diff := cmp.Diff(got, want, cmp.AllowUnexported(integerWindowSumArrayCursor{}), cmpOptions); diff != "" {
			t.Fatalf("did not get expected cursor; -got/+want:\n%v", diff)
		}
	})

	t.Run("Min", func(t *testing.T) {
		want := &integerWindowMinArrayCursor{
			IntegerArrayCursor: &MockIntegerArrayCursor{},
			res:                cursors.NewIntegerArrayLen(1),
			tmp:                &cursors.IntegerArray{},
		}

		agg := []*datatypes.Aggregate{
			&datatypes.Aggregate{Type: datatypes.Aggregate_AggregateTypeMin},
		}

		got, _ := newAggregateArrayCursor(context.Background(), agg, &MockIntegerArrayCursor{})

		if diff := cmp.Diff(got, want, cmp.AllowUnexported(integerWindowMinArrayCursor{}), cmpOptions); diff != "" {
			t.Fatalf("did not get expected cursor; -got/+want:\n%v", diff)
		}
	})

	t.Run("Max", func(t *testing.T) {
		want := &integerWindowMaxArrayCursor{
			IntegerArrayCursor: &MockIntegerArrayCursor{},
			res:                cursors.NewIntegerArrayLen(1),
			tmp:                &cursors.IntegerArray{},
		}

		agg := []*datatypes.Aggregate{
			&datatypes.Aggregate{Type: datatypes.Aggregate_AggregateTypeMax},
		}

		got, _ := newAggregateArrayCursor(context.Background(), agg, &MockIntegerArrayCursor{})

		if diff := cmp.Diff(got, want, cmp.AllowUnexported(integerWindowMaxArrayCursor{}), cmpOptions); diff != "" {
			t.Fatalf("did not get expected cursor; -got/+want:\n%v", diff)
		}
	})

	t.Run("Mean", func(t *testing.T) {
		want := &integerWindowMeanArrayCursor{
			IntegerArrayCursor: &MockIntegerArrayCursor{},
			res:                cursors.NewFloatArrayLen(1),
			tmp:                &cursors.IntegerArray{},
		}

		agg := []*datatypes.Aggregate{
			&datatypes.Aggregate{Type: datatypes.Aggregate_AggregateTypeMean},
		}

		got, _ := newAggregateArrayCursor(context.Background(), agg, &MockIntegerArrayCursor{})

		if diff := cmp.Diff(got, want, cmp.AllowUnexported(integerWindowMeanArrayCursor{}), cmpOptions); diff != "" {
			t.Fatalf("did not get expected cursor; -got/+want:\n%v", diff)
		}
	})

	t.Run("MeanCount", func(t *testing.T) {
		want := &integerWindowMeanCountArrayCursor{
			IntegerArrayCursor: &MockIntegerArrayCursor{},
			res:                cursors.NewMeanCountArrayLen(1),
			tmp:                &cursors.IntegerArray{},
		}

		agg := []*datatypes.Aggregate{
			&datatypes.Aggregate{Type: datatypes.Aggregate_AggregateTypeMean},
			&datatypes.Aggregate{Type: datatypes.Aggregate_AggregateTypeCount},
		}

		got, _ := newAggregateArrayCursor(context.Background(), agg, &MockIntegerArrayCursor{})

		if diff := cmp.Diff(got, want, cmp.AllowUnexported(integerWindowMeanCountArrayCursor{}), cmpOptions); diff != "" {
			t.Fatalf("did not get expected cursor; -got/+want:\n%v", diff)
		}
	})

}

func TestNewWindowAggregateArrayCursorMonths_Integer(t *testing.T) {

	t.Run("Count", func(t *testing.T) {
		window, _ := interval.NewWindow(
			values.MakeDuration(int64(time.Hour), 0, false),
			values.MakeDuration(int64(time.Hour), 0, false),
			values.MakeDuration(0, 0, false),
		)

		want := &integerWindowCountArrayCursor{
			IntegerArrayCursor: &MockIntegerArrayCursor{},
			res:                cursors.NewIntegerArrayLen(MaxPointsPerBlock),
			tmp:                &cursors.IntegerArray{},
			window:             window,
		}

		agg := []*datatypes.Aggregate{
			&datatypes.Aggregate{Type: datatypes.Aggregate_AggregateTypeCount},
		}

		got, _ := NewWindowAggregateArrayCursor(context.Background(), agg, window, &MockIntegerArrayCursor{})

		if diff := cmp.Diff(got, want, cmp.AllowUnexported(integerWindowCountArrayCursor{}), cmpOptions); diff != "" {
			t.Fatalf("did not get expected cursor; -got/+want:\n%v", diff)
		}
	})

	t.Run("Sum", func(t *testing.T) {
		window, _ := interval.NewWindow(
			values.MakeDuration(int64(time.Hour), 0, false),
			values.MakeDuration(int64(time.Hour), 0, false),
			values.MakeDuration(0, 0, false),
		)

		want := &integerWindowSumArrayCursor{
			IntegerArrayCursor: &MockIntegerArrayCursor{},
			res:                cursors.NewIntegerArrayLen(MaxPointsPerBlock),
			tmp:                &cursors.IntegerArray{},
			window:             window,
		}

		agg := []*datatypes.Aggregate{
			&datatypes.Aggregate{Type: datatypes.Aggregate_AggregateTypeSum},
		}

		got, _ := NewWindowAggregateArrayCursor(context.Background(), agg, window, &MockIntegerArrayCursor{})

		if diff := cmp.Diff(got, want, cmp.AllowUnexported(integerWindowSumArrayCursor{}), cmpOptions); diff != "" {
			t.Fatalf("did not get expected cursor; -got/+want:\n%v", diff)
		}
	})

	t.Run("Min", func(t *testing.T) {
		window, _ := interval.NewWindow(
			values.MakeDuration(int64(time.Hour), 0, false),
			values.MakeDuration(int64(time.Hour), 0, false),
			values.MakeDuration(0, 0, false),
		)

		want := &integerWindowMinArrayCursor{
			IntegerArrayCursor: &MockIntegerArrayCursor{},
			res:                cursors.NewIntegerArrayLen(MaxPointsPerBlock),
			tmp:                &cursors.IntegerArray{},
			window:             window,
		}

		agg := []*datatypes.Aggregate{
			&datatypes.Aggregate{Type: datatypes.Aggregate_AggregateTypeMin},
		}

		got, _ := NewWindowAggregateArrayCursor(context.Background(), agg, window, &MockIntegerArrayCursor{})

		if diff := cmp.Diff(got, want, cmp.AllowUnexported(integerWindowMinArrayCursor{}), cmpOptions); diff != "" {
			t.Fatalf("did not get expected cursor; -got/+want:\n%v", diff)
		}
	})

	t.Run("Max", func(t *testing.T) {
		window, _ := interval.NewWindow(
			values.MakeDuration(int64(time.Hour), 0, false),
			values.MakeDuration(int64(time.Hour), 0, false),
			values.MakeDuration(0, 0, false),
		)

		want := &integerWindowMaxArrayCursor{
			IntegerArrayCursor: &MockIntegerArrayCursor{},
			res:                cursors.NewIntegerArrayLen(MaxPointsPerBlock),
			tmp:                &cursors.IntegerArray{},
			window:             window,
		}

		agg := []*datatypes.Aggregate{
			&datatypes.Aggregate{Type: datatypes.Aggregate_AggregateTypeMax},
		}

		got, _ := NewWindowAggregateArrayCursor(context.Background(), agg, window, &MockIntegerArrayCursor{})

		if diff := cmp.Diff(got, want, cmp.AllowUnexported(integerWindowMaxArrayCursor{}), cmpOptions); diff != "" {
			t.Fatalf("did not get expected cursor; -got/+want:\n%v", diff)
		}
	})

	t.Run("Mean", func(t *testing.T) {
		window, _ := interval.NewWindow(
			values.MakeDuration(int64(time.Hour), 0, false),
			values.MakeDuration(int64(time.Hour), 0, false),
			values.MakeDuration(0, 0, false),
		)

		want := &integerWindowMeanArrayCursor{
			IntegerArrayCursor: &MockIntegerArrayCursor{},
			res:                cursors.NewFloatArrayLen(MaxPointsPerBlock),
			tmp:                &cursors.IntegerArray{},
			window:             window,
		}

		agg := []*datatypes.Aggregate{
			&datatypes.Aggregate{Type: datatypes.Aggregate_AggregateTypeMean},
		}

		got, _ := NewWindowAggregateArrayCursor(context.Background(), agg, window, &MockIntegerArrayCursor{})

		if diff := cmp.Diff(got, want, cmp.AllowUnexported(integerWindowMeanArrayCursor{}), cmpOptions); diff != "" {
			t.Fatalf("did not get expected cursor; -got/+want:\n%v", diff)
		}
	})

	t.Run("MeanCount", func(t *testing.T) {
		window, _ := interval.NewWindow(
			values.MakeDuration(int64(time.Hour), 0, false),
			values.MakeDuration(int64(time.Hour), 0, false),
			values.MakeDuration(0, 0, false),
		)

		want := &integerWindowMeanCountArrayCursor{
			IntegerArrayCursor: &MockIntegerArrayCursor{},
			res:                cursors.NewMeanCountArrayLen(MaxPointsPerBlock),
			tmp:                &cursors.IntegerArray{},
			window:             window,
		}

		agg := []*datatypes.Aggregate{
			&datatypes.Aggregate{Type: datatypes.Aggregate_AggregateTypeMean},
			&datatypes.Aggregate{Type: datatypes.Aggregate_AggregateTypeCount},
		}

		got, _ := NewWindowAggregateArrayCursor(context.Background(), agg, window, &MockIntegerArrayCursor{})

		if diff := cmp.Diff(got, want, cmp.AllowUnexported(integerWindowMeanCountArrayCursor{}), cmpOptions); diff != "" {
			t.Fatalf("did not get expected cursor; -got/+want:\n%v", diff)
		}
	})

}

func TestNewWindowAggregateArrayCursor_Integer(t *testing.T) {

	t.Run("Count", func(t *testing.T) {
		window, _ := interval.NewWindow(
			values.MakeDuration(0, 1, false),
			values.MakeDuration(0, 1, false),
			values.MakeDuration(0, 0, false),
		)

		want := &integerWindowCountArrayCursor{
			IntegerArrayCursor: &MockIntegerArrayCursor{},
			res:                cursors.NewIntegerArrayLen(MaxPointsPerBlock),
			tmp:                &cursors.IntegerArray{},
			window:             window,
		}

		agg := []*datatypes.Aggregate{
			&datatypes.Aggregate{Type: datatypes.Aggregate_AggregateTypeCount},
		}

		got, _ := NewWindowAggregateArrayCursor(context.Background(), agg, window, &MockIntegerArrayCursor{})

		if diff := cmp.Diff(got, want, cmp.AllowUnexported(integerWindowCountArrayCursor{}), cmpOptions); diff != "" {
			t.Fatalf("did not get expected cursor; -got/+want:\n%v", diff)
		}
	})

	t.Run("Sum", func(t *testing.T) {
		window, _ := interval.NewWindow(
			values.MakeDuration(0, 1, false),
			values.MakeDuration(0, 1, false),
			values.MakeDuration(0, 0, false),
		)

		want := &integerWindowSumArrayCursor{
			IntegerArrayCursor: &MockIntegerArrayCursor{},
			res:                cursors.NewIntegerArrayLen(MaxPointsPerBlock),
			tmp:                &cursors.IntegerArray{},
			window:             window,
		}

		agg := []*datatypes.Aggregate{
			&datatypes.Aggregate{Type: datatypes.Aggregate_AggregateTypeSum},
		}

		got, _ := NewWindowAggregateArrayCursor(context.Background(), agg, window, &MockIntegerArrayCursor{})

		if diff := cmp.Diff(got, want, cmp.AllowUnexported(integerWindowSumArrayCursor{}), cmpOptions); diff != "" {
			t.Fatalf("did not get expected cursor; -got/+want:\n%v", diff)
		}
	})

	t.Run("Min", func(t *testing.T) {
		window, _ := interval.NewWindow(
			values.MakeDuration(0, 1, false),
			values.MakeDuration(0, 1, false),
			values.MakeDuration(0, 0, false),
		)

		want := &integerWindowMinArrayCursor{
			IntegerArrayCursor: &MockIntegerArrayCursor{},
			res:                cursors.NewIntegerArrayLen(MaxPointsPerBlock),
			tmp:                &cursors.IntegerArray{},
			window:             window,
		}

		agg := []*datatypes.Aggregate{
			&datatypes.Aggregate{Type: datatypes.Aggregate_AggregateTypeMin},
		}

		got, _ := NewWindowAggregateArrayCursor(context.Background(), agg, window, &MockIntegerArrayCursor{})

		if diff := cmp.Diff(got, want, cmp.AllowUnexported(integerWindowMinArrayCursor{}), cmpOptions); diff != "" {
			t.Fatalf("did not get expected cursor; -got/+want:\n%v", diff)
		}
	})

	t.Run("Max", func(t *testing.T) {
		window, _ := interval.NewWindow(
			values.MakeDuration(0, 1, false),
			values.MakeDuration(0, 1, false),
			values.MakeDuration(0, 0, false),
		)

		want := &integerWindowMaxArrayCursor{
			IntegerArrayCursor: &MockIntegerArrayCursor{},
			res:                cursors.NewIntegerArrayLen(MaxPointsPerBlock),
			tmp:                &cursors.IntegerArray{},
			window:             window,
		}

		agg := []*datatypes.Aggregate{
			&datatypes.Aggregate{Type: datatypes.Aggregate_AggregateTypeMax},
		}

		got, _ := NewWindowAggregateArrayCursor(context.Background(), agg, window, &MockIntegerArrayCursor{})

		if diff := cmp.Diff(got, want, cmp.AllowUnexported(integerWindowMaxArrayCursor{}), cmpOptions); diff != "" {
			t.Fatalf("did not get expected cursor; -got/+want:\n%v", diff)
		}
	})

	t.Run("Mean", func(t *testing.T) {
		window, _ := interval.NewWindow(
			values.MakeDuration(0, 1, false),
			values.MakeDuration(0, 1, false),
			values.MakeDuration(0, 0, false),
		)

		want := &integerWindowMeanArrayCursor{
			IntegerArrayCursor: &MockIntegerArrayCursor{},
			res:                cursors.NewFloatArrayLen(MaxPointsPerBlock),
			tmp:                &cursors.IntegerArray{},
			window:             window,
		}

		agg := []*datatypes.Aggregate{
			&datatypes.Aggregate{Type: datatypes.Aggregate_AggregateTypeMean},
		}

		got, _ := NewWindowAggregateArrayCursor(context.Background(), agg, window, &MockIntegerArrayCursor{})

		if diff := cmp.Diff(got, want, cmp.AllowUnexported(integerWindowMeanArrayCursor{}), cmpOptions); diff != "" {
			t.Fatalf("did not get expected cursor; -got/+want:\n%v", diff)
		}
	})

	t.Run("MeanCount", func(t *testing.T) {
		window, _ := interval.NewWindow(
			values.MakeDuration(0, 1, false),
			values.MakeDuration(0, 1, false),
			values.MakeDuration(0, 0, false),
		)

		want := &integerWindowMeanCountArrayCursor{
			IntegerArrayCursor: &MockIntegerArrayCursor{},
			res:                cursors.NewMeanCountArrayLen(MaxPointsPerBlock),
			tmp:                &cursors.IntegerArray{},
			window:             window,
		}

		agg := []*datatypes.Aggregate{
			&datatypes.Aggregate{Type: datatypes.Aggregate_AggregateTypeMean},
			&datatypes.Aggregate{Type: datatypes.Aggregate_AggregateTypeCount},
		}

		got, _ := NewWindowAggregateArrayCursor(context.Background(), agg, window, &MockIntegerArrayCursor{})

		if diff := cmp.Diff(got, want, cmp.AllowUnexported(integerWindowMeanCountArrayCursor{}), cmpOptions); diff != "" {
			t.Fatalf("did not get expected cursor; -got/+want:\n%v", diff)
		}
	})

}

type MockUnsignedArrayCursor struct {
	CloseFunc func()
	ErrFunc   func() error
	StatsFunc func() cursors.CursorStats
	NextFunc  func() *cursors.UnsignedArray
}

func (c *MockUnsignedArrayCursor) Close()                       { c.CloseFunc() }
func (c *MockUnsignedArrayCursor) Err() error                   { return c.ErrFunc() }
func (c *MockUnsignedArrayCursor) Stats() cursors.CursorStats   { return c.StatsFunc() }
func (c *MockUnsignedArrayCursor) Next() *cursors.UnsignedArray { return c.NextFunc() }

func TestNewAggregateArrayCursor_Unsigned(t *testing.T) {

	t.Run("Count", func(t *testing.T) {
		want := &unsignedWindowCountArrayCursor{
			UnsignedArrayCursor: &MockUnsignedArrayCursor{},
			res:                 cursors.NewIntegerArrayLen(1),
			tmp:                 &cursors.UnsignedArray{},
		}

		agg := []*datatypes.Aggregate{
			&datatypes.Aggregate{Type: datatypes.Aggregate_AggregateTypeCount},
		}

		got, _ := newAggregateArrayCursor(context.Background(), agg, &MockUnsignedArrayCursor{})

		if diff := cmp.Diff(got, want, cmp.AllowUnexported(unsignedWindowCountArrayCursor{}), cmpOptions); diff != "" {
			t.Fatalf("did not get expected cursor; -got/+want:\n%v", diff)
		}
	})

	t.Run("Sum", func(t *testing.T) {
		want := &unsignedWindowSumArrayCursor{
			UnsignedArrayCursor: &MockUnsignedArrayCursor{},
			res:                 cursors.NewUnsignedArrayLen(1),
			tmp:                 &cursors.UnsignedArray{},
		}

		agg := []*datatypes.Aggregate{
			&datatypes.Aggregate{Type: datatypes.Aggregate_AggregateTypeSum},
		}

		got, _ := newAggregateArrayCursor(context.Background(), agg, &MockUnsignedArrayCursor{})

		if diff := cmp.Diff(got, want, cmp.AllowUnexported(unsignedWindowSumArrayCursor{}), cmpOptions); diff != "" {
			t.Fatalf("did not get expected cursor; -got/+want:\n%v", diff)
		}
	})

	t.Run("Min", func(t *testing.T) {
		want := &unsignedWindowMinArrayCursor{
			UnsignedArrayCursor: &MockUnsignedArrayCursor{},
			res:                 cursors.NewUnsignedArrayLen(1),
			tmp:                 &cursors.UnsignedArray{},
		}

		agg := []*datatypes.Aggregate{
			&datatypes.Aggregate{Type: datatypes.Aggregate_AggregateTypeMin},
		}

		got, _ := newAggregateArrayCursor(context.Background(), agg, &MockUnsignedArrayCursor{})

		if diff := cmp.Diff(got, want, cmp.AllowUnexported(unsignedWindowMinArrayCursor{}), cmpOptions); diff != "" {
			t.Fatalf("did not get expected cursor; -got/+want:\n%v", diff)
		}
	})

	t.Run("Max", func(t *testing.T) {
		want := &unsignedWindowMaxArrayCursor{
			UnsignedArrayCursor: &MockUnsignedArrayCursor{},
			res:                 cursors.NewUnsignedArrayLen(1),
			tmp:                 &cursors.UnsignedArray{},
		}

		agg := []*datatypes.Aggregate{
			&datatypes.Aggregate{Type: datatypes.Aggregate_AggregateTypeMax},
		}

		got, _ := newAggregateArrayCursor(context.Background(), agg, &MockUnsignedArrayCursor{})

		if diff := cmp.Diff(got, want, cmp.AllowUnexported(unsignedWindowMaxArrayCursor{}), cmpOptions); diff != "" {
			t.Fatalf("did not get expected cursor; -got/+want:\n%v", diff)
		}
	})

	t.Run("Mean", func(t *testing.T) {
		want := &unsignedWindowMeanArrayCursor{
			UnsignedArrayCursor: &MockUnsignedArrayCursor{},
			res:                 cursors.NewFloatArrayLen(1),
			tmp:                 &cursors.UnsignedArray{},
		}

		agg := []*datatypes.Aggregate{
			&datatypes.Aggregate{Type: datatypes.Aggregate_AggregateTypeMean},
		}

		got, _ := newAggregateArrayCursor(context.Background(), agg, &MockUnsignedArrayCursor{})

		if diff := cmp.Diff(got, want, cmp.AllowUnexported(unsignedWindowMeanArrayCursor{}), cmpOptions); diff != "" {
			t.Fatalf("did not get expected cursor; -got/+want:\n%v", diff)
		}
	})

	t.Run("MeanCount", func(t *testing.T) {
		want := &unsignedWindowMeanCountArrayCursor{
			UnsignedArrayCursor: &MockUnsignedArrayCursor{},
			res:                 cursors.NewMeanCountArrayLen(1),
			tmp:                 &cursors.UnsignedArray{},
		}

		agg := []*datatypes.Aggregate{
			&datatypes.Aggregate{Type: datatypes.Aggregate_AggregateTypeMean},
			&datatypes.Aggregate{Type: datatypes.Aggregate_AggregateTypeCount},
		}

		got, _ := newAggregateArrayCursor(context.Background(), agg, &MockUnsignedArrayCursor{})

		if diff := cmp.Diff(got, want, cmp.AllowUnexported(unsignedWindowMeanCountArrayCursor{}), cmpOptions); diff != "" {
			t.Fatalf("did not get expected cursor; -got/+want:\n%v", diff)
		}
	})

}

func TestNewWindowAggregateArrayCursorMonths_Unsigned(t *testing.T) {

	t.Run("Count", func(t *testing.T) {
		window, _ := interval.NewWindow(
			values.MakeDuration(int64(time.Hour), 0, false),
			values.MakeDuration(int64(time.Hour), 0, false),
			values.MakeDuration(0, 0, false),
		)

		want := &unsignedWindowCountArrayCursor{
			UnsignedArrayCursor: &MockUnsignedArrayCursor{},
			res:                 cursors.NewIntegerArrayLen(MaxPointsPerBlock),
			tmp:                 &cursors.UnsignedArray{},
			window:              window,
		}

		agg := []*datatypes.Aggregate{
			&datatypes.Aggregate{Type: datatypes.Aggregate_AggregateTypeCount},
		}

		got, _ := NewWindowAggregateArrayCursor(context.Background(), agg, window, &MockUnsignedArrayCursor{})

		if diff := cmp.Diff(got, want, cmp.AllowUnexported(unsignedWindowCountArrayCursor{}), cmpOptions); diff != "" {
			t.Fatalf("did not get expected cursor; -got/+want:\n%v", diff)
		}
	})

	t.Run("Sum", func(t *testing.T) {
		window, _ := interval.NewWindow(
			values.MakeDuration(int64(time.Hour), 0, false),
			values.MakeDuration(int64(time.Hour), 0, false),
			values.MakeDuration(0, 0, false),
		)

		want := &unsignedWindowSumArrayCursor{
			UnsignedArrayCursor: &MockUnsignedArrayCursor{},
			res:                 cursors.NewUnsignedArrayLen(MaxPointsPerBlock),
			tmp:                 &cursors.UnsignedArray{},
			window:              window,
		}

		agg := []*datatypes.Aggregate{
			&datatypes.Aggregate{Type: datatypes.Aggregate_AggregateTypeSum},
		}

		got, _ := NewWindowAggregateArrayCursor(context.Background(), agg, window, &MockUnsignedArrayCursor{})

		if diff := cmp.Diff(got, want, cmp.AllowUnexported(unsignedWindowSumArrayCursor{}), cmpOptions); diff != "" {
			t.Fatalf("did not get expected cursor; -got/+want:\n%v", diff)
		}
	})

	t.Run("Min", func(t *testing.T) {
		window, _ := interval.NewWindow(
			values.MakeDuration(int64(time.Hour), 0, false),
			values.MakeDuration(int64(time.Hour), 0, false),
			values.MakeDuration(0, 0, false),
		)

		want := &unsignedWindowMinArrayCursor{
			UnsignedArrayCursor: &MockUnsignedArrayCursor{},
			res:                 cursors.NewUnsignedArrayLen(MaxPointsPerBlock),
			tmp:                 &cursors.UnsignedArray{},
			window:              window,
		}

		agg := []*datatypes.Aggregate{
			&datatypes.Aggregate{Type: datatypes.Aggregate_AggregateTypeMin},
		}

		got, _ := NewWindowAggregateArrayCursor(context.Background(), agg, window, &MockUnsignedArrayCursor{})

		if diff := cmp.Diff(got, want, cmp.AllowUnexported(unsignedWindowMinArrayCursor{}), cmpOptions); diff != "" {
			t.Fatalf("did not get expected cursor; -got/+want:\n%v", diff)
		}
	})

	t.Run("Max", func(t *testing.T) {
		window, _ := interval.NewWindow(
			values.MakeDuration(int64(time.Hour), 0, false),
			values.MakeDuration(int64(time.Hour), 0, false),
			values.MakeDuration(0, 0, false),
		)

		want := &unsignedWindowMaxArrayCursor{
			UnsignedArrayCursor: &MockUnsignedArrayCursor{},
			res:                 cursors.NewUnsignedArrayLen(MaxPointsPerBlock),
			tmp:                 &cursors.UnsignedArray{},
			window:              window,
		}

		agg := []*datatypes.Aggregate{
			&datatypes.Aggregate{Type: datatypes.Aggregate_AggregateTypeMax},
		}

		got, _ := NewWindowAggregateArrayCursor(context.Background(), agg, window, &MockUnsignedArrayCursor{})

		if diff := cmp.Diff(got, want, cmp.AllowUnexported(unsignedWindowMaxArrayCursor{}), cmpOptions); diff != "" {
			t.Fatalf("did not get expected cursor; -got/+want:\n%v", diff)
		}
	})

	t.Run("Mean", func(t *testing.T) {
		window, _ := interval.NewWindow(
			values.MakeDuration(int64(time.Hour), 0, false),
			values.MakeDuration(int64(time.Hour), 0, false),
			values.MakeDuration(0, 0, false),
		)

		want := &unsignedWindowMeanArrayCursor{
			UnsignedArrayCursor: &MockUnsignedArrayCursor{},
			res:                 cursors.NewFloatArrayLen(MaxPointsPerBlock),
			tmp:                 &cursors.UnsignedArray{},
			window:              window,
		}

		agg := []*datatypes.Aggregate{
			&datatypes.Aggregate{Type: datatypes.Aggregate_AggregateTypeMean},
		}

		got, _ := NewWindowAggregateArrayCursor(context.Background(), agg, window, &MockUnsignedArrayCursor{})

		if diff := cmp.Diff(got, want, cmp.AllowUnexported(unsignedWindowMeanArrayCursor{}), cmpOptions); diff != "" {
			t.Fatalf("did not get expected cursor; -got/+want:\n%v", diff)
		}
	})

	t.Run("MeanCount", func(t *testing.T) {
		window, _ := interval.NewWindow(
			values.MakeDuration(int64(time.Hour), 0, false),
			values.MakeDuration(int64(time.Hour), 0, false),
			values.MakeDuration(0, 0, false),
		)

		want := &unsignedWindowMeanCountArrayCursor{
			UnsignedArrayCursor: &MockUnsignedArrayCursor{},
			res:                 cursors.NewMeanCountArrayLen(MaxPointsPerBlock),
			tmp:                 &cursors.UnsignedArray{},
			window:              window,
		}

		agg := []*datatypes.Aggregate{
			&datatypes.Aggregate{Type: datatypes.Aggregate_AggregateTypeMean},
			&datatypes.Aggregate{Type: datatypes.Aggregate_AggregateTypeCount},
		}

		got, _ := NewWindowAggregateArrayCursor(context.Background(), agg, window, &MockUnsignedArrayCursor{})

		if diff := cmp.Diff(got, want, cmp.AllowUnexported(unsignedWindowMeanCountArrayCursor{}), cmpOptions); diff != "" {
			t.Fatalf("did not get expected cursor; -got/+want:\n%v", diff)
		}
	})

}

func TestNewWindowAggregateArrayCursor_Unsigned(t *testing.T) {

	t.Run("Count", func(t *testing.T) {
		window, _ := interval.NewWindow(
			values.MakeDuration(0, 1, false),
			values.MakeDuration(0, 1, false),
			values.MakeDuration(0, 0, false),
		)

		want := &unsignedWindowCountArrayCursor{
			UnsignedArrayCursor: &MockUnsignedArrayCursor{},
			res:                 cursors.NewIntegerArrayLen(MaxPointsPerBlock),
			tmp:                 &cursors.UnsignedArray{},
			window:              window,
		}

		agg := []*datatypes.Aggregate{
			&datatypes.Aggregate{Type: datatypes.Aggregate_AggregateTypeCount},
		}

		got, _ := NewWindowAggregateArrayCursor(context.Background(), agg, window, &MockUnsignedArrayCursor{})

		if diff := cmp.Diff(got, want, cmp.AllowUnexported(unsignedWindowCountArrayCursor{}), cmpOptions); diff != "" {
			t.Fatalf("did not get expected cursor; -got/+want:\n%v", diff)
		}
	})

	t.Run("Sum", func(t *testing.T) {
		window, _ := interval.NewWindow(
			values.MakeDuration(0, 1, false),
			values.MakeDuration(0, 1, false),
			values.MakeDuration(0, 0, false),
		)

		want := &unsignedWindowSumArrayCursor{
			UnsignedArrayCursor: &MockUnsignedArrayCursor{},
			res:                 cursors.NewUnsignedArrayLen(MaxPointsPerBlock),
			tmp:                 &cursors.UnsignedArray{},
			window:              window,
		}

		agg := []*datatypes.Aggregate{
			&datatypes.Aggregate{Type: datatypes.Aggregate_AggregateTypeSum},
		}

		got, _ := NewWindowAggregateArrayCursor(context.Background(), agg, window, &MockUnsignedArrayCursor{})

		if diff := cmp.Diff(got, want, cmp.AllowUnexported(unsignedWindowSumArrayCursor{}), cmpOptions); diff != "" {
			t.Fatalf("did not get expected cursor; -got/+want:\n%v", diff)
		}
	})

	t.Run("Min", func(t *testing.T) {
		window, _ := interval.NewWindow(
			values.MakeDuration(0, 1, false),
			values.MakeDuration(0, 1, false),
			values.MakeDuration(0, 0, false),
		)

		want := &unsignedWindowMinArrayCursor{
			UnsignedArrayCursor: &MockUnsignedArrayCursor{},
			res:                 cursors.NewUnsignedArrayLen(MaxPointsPerBlock),
			tmp:                 &cursors.UnsignedArray{},
			window:              window,
		}

		agg := []*datatypes.Aggregate{
			&datatypes.Aggregate{Type: datatypes.Aggregate_AggregateTypeMin},
		}

		got, _ := NewWindowAggregateArrayCursor(context.Background(), agg, window, &MockUnsignedArrayCursor{})

		if diff := cmp.Diff(got, want, cmp.AllowUnexported(unsignedWindowMinArrayCursor{}), cmpOptions); diff != "" {
			t.Fatalf("did not get expected cursor; -got/+want:\n%v", diff)
		}
	})

	t.Run("Max", func(t *testing.T) {
		window, _ := interval.NewWindow(
			values.MakeDuration(0, 1, false),
			values.MakeDuration(0, 1, false),
			values.MakeDuration(0, 0, false),
		)

		want := &unsignedWindowMaxArrayCursor{
			UnsignedArrayCursor: &MockUnsignedArrayCursor{},
			res:                 cursors.NewUnsignedArrayLen(MaxPointsPerBlock),
			tmp:                 &cursors.UnsignedArray{},
			window:              window,
		}

		agg := []*datatypes.Aggregate{
			&datatypes.Aggregate{Type: datatypes.Aggregate_AggregateTypeMax},
		}

		got, _ := NewWindowAggregateArrayCursor(context.Background(), agg, window, &MockUnsignedArrayCursor{})

		if diff := cmp.Diff(got, want, cmp.AllowUnexported(unsignedWindowMaxArrayCursor{}), cmpOptions); diff != "" {
			t.Fatalf("did not get expected cursor; -got/+want:\n%v", diff)
		}
	})

	t.Run("Mean", func(t *testing.T) {
		window, _ := interval.NewWindow(
			values.MakeDuration(0, 1, false),
			values.MakeDuration(0, 1, false),
			values.MakeDuration(0, 0, false),
		)

		want := &unsignedWindowMeanArrayCursor{
			UnsignedArrayCursor: &MockUnsignedArrayCursor{},
			res:                 cursors.NewFloatArrayLen(MaxPointsPerBlock),
			tmp:                 &cursors.UnsignedArray{},
			window:              window,
		}

		agg := []*datatypes.Aggregate{
			&datatypes.Aggregate{Type: datatypes.Aggregate_AggregateTypeMean},
		}

		got, _ := NewWindowAggregateArrayCursor(context.Background(), agg, window, &MockUnsignedArrayCursor{})

		if diff := cmp.Diff(got, want, cmp.AllowUnexported(unsignedWindowMeanArrayCursor{}), cmpOptions); diff != "" {
			t.Fatalf("did not get expected cursor; -got/+want:\n%v", diff)
		}
	})

	t.Run("MeanCount", func(t *testing.T) {
		window, _ := interval.NewWindow(
			values.MakeDuration(0, 1, false),
			values.MakeDuration(0, 1, false),
			values.MakeDuration(0, 0, false),
		)

		want := &unsignedWindowMeanCountArrayCursor{
			UnsignedArrayCursor: &MockUnsignedArrayCursor{},
			res:                 cursors.NewMeanCountArrayLen(MaxPointsPerBlock),
			tmp:                 &cursors.UnsignedArray{},
			window:              window,
		}

		agg := []*datatypes.Aggregate{
			&datatypes.Aggregate{Type: datatypes.Aggregate_AggregateTypeMean},
			&datatypes.Aggregate{Type: datatypes.Aggregate_AggregateTypeCount},
		}

		got, _ := NewWindowAggregateArrayCursor(context.Background(), agg, window, &MockUnsignedArrayCursor{})

		if diff := cmp.Diff(got, want, cmp.AllowUnexported(unsignedWindowMeanCountArrayCursor{}), cmpOptions); diff != "" {
			t.Fatalf("did not get expected cursor; -got/+want:\n%v", diff)
		}
	})

}

type MockStringArrayCursor struct {
	CloseFunc func()
	ErrFunc   func() error
	StatsFunc func() cursors.CursorStats
	NextFunc  func() *cursors.StringArray
}

func (c *MockStringArrayCursor) Close()                     { c.CloseFunc() }
func (c *MockStringArrayCursor) Err() error                 { return c.ErrFunc() }
func (c *MockStringArrayCursor) Stats() cursors.CursorStats { return c.StatsFunc() }
func (c *MockStringArrayCursor) Next() *cursors.StringArray { return c.NextFunc() }

func TestNewAggregateArrayCursor_String(t *testing.T) {

	t.Run("Count", func(t *testing.T) {
		want := &stringWindowCountArrayCursor{
			StringArrayCursor: &MockStringArrayCursor{},
			res:               cursors.NewIntegerArrayLen(1),
			tmp:               &cursors.StringArray{},
		}

		agg := []*datatypes.Aggregate{
			&datatypes.Aggregate{Type: datatypes.Aggregate_AggregateTypeCount},
		}

		got, _ := newAggregateArrayCursor(context.Background(), agg, &MockStringArrayCursor{})

		if diff := cmp.Diff(got, want, cmp.AllowUnexported(stringWindowCountArrayCursor{}), cmpOptions); diff != "" {
			t.Fatalf("did not get expected cursor; -got/+want:\n%v", diff)
		}
	})

}

func TestNewWindowAggregateArrayCursorMonths_String(t *testing.T) {

	t.Run("Count", func(t *testing.T) {
		window, _ := interval.NewWindow(
			values.MakeDuration(int64(time.Hour), 0, false),
			values.MakeDuration(int64(time.Hour), 0, false),
			values.MakeDuration(0, 0, false),
		)

		want := &stringWindowCountArrayCursor{
			StringArrayCursor: &MockStringArrayCursor{},
			res:               cursors.NewIntegerArrayLen(MaxPointsPerBlock),
			tmp:               &cursors.StringArray{},
			window:            window,
		}

		agg := []*datatypes.Aggregate{
			&datatypes.Aggregate{Type: datatypes.Aggregate_AggregateTypeCount},
		}

		got, _ := NewWindowAggregateArrayCursor(context.Background(), agg, window, &MockStringArrayCursor{})

		if diff := cmp.Diff(got, want, cmp.AllowUnexported(stringWindowCountArrayCursor{}), cmpOptions); diff != "" {
			t.Fatalf("did not get expected cursor; -got/+want:\n%v", diff)
		}
	})

}

func TestNewWindowAggregateArrayCursor_String(t *testing.T) {

	t.Run("Count", func(t *testing.T) {
		window, _ := interval.NewWindow(
			values.MakeDuration(0, 1, false),
			values.MakeDuration(0, 1, false),
			values.MakeDuration(0, 0, false),
		)

		want := &stringWindowCountArrayCursor{
			StringArrayCursor: &MockStringArrayCursor{},
			res:               cursors.NewIntegerArrayLen(MaxPointsPerBlock),
			tmp:               &cursors.StringArray{},
			window:            window,
		}

		agg := []*datatypes.Aggregate{
			&datatypes.Aggregate{Type: datatypes.Aggregate_AggregateTypeCount},
		}

		got, _ := NewWindowAggregateArrayCursor(context.Background(), agg, window, &MockStringArrayCursor{})

		if diff := cmp.Diff(got, want, cmp.AllowUnexported(stringWindowCountArrayCursor{}), cmpOptions); diff != "" {
			t.Fatalf("did not get expected cursor; -got/+want:\n%v", diff)
		}
	})

}

type MockBooleanArrayCursor struct {
	CloseFunc func()
	ErrFunc   func() error
	StatsFunc func() cursors.CursorStats
	NextFunc  func() *cursors.BooleanArray
}

func (c *MockBooleanArrayCursor) Close()                      { c.CloseFunc() }
func (c *MockBooleanArrayCursor) Err() error                  { return c.ErrFunc() }
func (c *MockBooleanArrayCursor) Stats() cursors.CursorStats  { return c.StatsFunc() }
func (c *MockBooleanArrayCursor) Next() *cursors.BooleanArray { return c.NextFunc() }

func TestNewAggregateArrayCursor_Boolean(t *testing.T) {

	t.Run("Count", func(t *testing.T) {
		want := &booleanWindowCountArrayCursor{
			BooleanArrayCursor: &MockBooleanArrayCursor{},
			res:                cursors.NewIntegerArrayLen(1),
			tmp:                &cursors.BooleanArray{},
		}

		agg := []*datatypes.Aggregate{
			&datatypes.Aggregate{Type: datatypes.Aggregate_AggregateTypeCount},
		}

		got, _ := newAggregateArrayCursor(context.Background(), agg, &MockBooleanArrayCursor{})

		if diff := cmp.Diff(got, want, cmp.AllowUnexported(booleanWindowCountArrayCursor{}), cmpOptions); diff != "" {
			t.Fatalf("did not get expected cursor; -got/+want:\n%v", diff)
		}
	})

}

func TestNewWindowAggregateArrayCursorMonths_Boolean(t *testing.T) {

	t.Run("Count", func(t *testing.T) {
		window, _ := interval.NewWindow(
			values.MakeDuration(int64(time.Hour), 0, false),
			values.MakeDuration(int64(time.Hour), 0, false),
			values.MakeDuration(0, 0, false),
		)

		want := &booleanWindowCountArrayCursor{
			BooleanArrayCursor: &MockBooleanArrayCursor{},
			res:                cursors.NewIntegerArrayLen(MaxPointsPerBlock),
			tmp:                &cursors.BooleanArray{},
			window:             window,
		}

		agg := []*datatypes.Aggregate{
			&datatypes.Aggregate{Type: datatypes.Aggregate_AggregateTypeCount},
		}

		got, _ := NewWindowAggregateArrayCursor(context.Background(), agg, window, &MockBooleanArrayCursor{})

		if diff := cmp.Diff(got, want, cmp.AllowUnexported(booleanWindowCountArrayCursor{}), cmpOptions); diff != "" {
			t.Fatalf("did not get expected cursor; -got/+want:\n%v", diff)
		}
	})

}

func TestNewWindowAggregateArrayCursor_Boolean(t *testing.T) {

	t.Run("Count", func(t *testing.T) {
		window, _ := interval.NewWindow(
			values.MakeDuration(0, 1, false),
			values.MakeDuration(0, 1, false),
			values.MakeDuration(0, 0, false),
		)

		want := &booleanWindowCountArrayCursor{
			BooleanArrayCursor: &MockBooleanArrayCursor{},
			res:                cursors.NewIntegerArrayLen(MaxPointsPerBlock),
			tmp:                &cursors.BooleanArray{},
			window:             window,
		}

		agg := []*datatypes.Aggregate{
			&datatypes.Aggregate{Type: datatypes.Aggregate_AggregateTypeCount},
		}

		got, _ := NewWindowAggregateArrayCursor(context.Background(), agg, window, &MockBooleanArrayCursor{})

		if diff := cmp.Diff(got, want, cmp.AllowUnexported(booleanWindowCountArrayCursor{}), cmpOptions); diff != "" {
			t.Fatalf("did not get expected cursor; -got/+want:\n%v", diff)
		}
	})

}
