// Copyright (c) 2024 Celestino Amoroso (celestino.amoroso@gmail.com).
// All rights reserved.

// t_iter-list_test.go
package expr

import (
	"io"
	"testing"
)

func TestNewListIterator(t *testing.T) {
	list := newListA("a", "b", "c", "d")
	it := NewListIterator(list, []any{1, 3, 1})
	if item, err := it.Next(); err != nil {
		t.Errorf("error: %v", err)
	} else if item != "b" {
		t.Errorf("expected %q, got %q", "b", item)
	} else {
		t.Logf("Next: %v", item)
	}
}

func TestNewListIterator2(t *testing.T) {
	list := newListA("a", "b", "c", "d")
	it := NewListIterator(list, []any{3, 1, -1})
	if item, err := it.Next(); err != nil {
		t.Errorf("error: %v", err)
	} else if item != "d" {
		t.Errorf("expected %q, got %q", "d", item)
	} else {
		t.Logf("Next: %v", item)
	}
}

func TestNewListIterator3(t *testing.T) {
	list := newListA("a", "b", "c", "d")
	it := NewListIterator(list, []any{1, -1, 1})
	if item, err := it.Next(); err != nil {
		t.Errorf("error: %v", err)
	} else if item != "b" {
		t.Errorf("expected %q, got %q", "b", item)
	} else {
		t.Logf("Next: %v", item)
	}
}

func TestNewIterList2(t *testing.T) {
	list := []any{"a", "b", "c", "d"}
	it := NewArrayIterator(list)
	if item, err := it.Next(); err != nil {
		t.Errorf("error: %v", err)
	} else if item != "a" {
		t.Errorf("expected %q, got %q", "a", item)
	} else {
		t.Logf("Next: %v", item)
	}
}

func TestNewIterList3(t *testing.T) {
	list := []any{"a", "b", "c", "d"}
	it := NewAnyIterator(list)
	if item, err := it.Next(); err != nil {
		t.Errorf("error: %v", err)
	} else if item != "a" {
		t.Errorf("expected %q, got %q", "a", item)
	} else {
		t.Logf("Next: %v", item)
	}
}

func TestNewIterList4(t *testing.T) {
	list := any(nil)
	it := NewAnyIterator(list)
	if _, err := it.Next(); err != io.EOF {
		t.Errorf("error: %v", err)
	}
}

func TestNewIterList5(t *testing.T) {
	list := "123"
	it := NewAnyIterator(list)
	if item, err := it.Next(); err != nil {
		t.Errorf("error: %v", err)
	} else if item != "123" {
		t.Errorf("expected %q, got %q", "123", item)
	} else {
		t.Logf("Next: %v", item)
	}
}

func TestNewIterList6(t *testing.T) {
	list := newListA("a", "b", "c", "d")
	it1 := NewAnyIterator(list)
	it := NewAnyIterator(it1)
	if item, err := it.Next(); err != nil {
		t.Errorf("error: %v", err)
	} else if item != "a" {
		t.Errorf("expected %q, got %q", "a", item)
	} else {
		t.Logf("Next: %v", item)
	}
}
func TestNewString(t *testing.T) {
	list := "123"
	it := NewAnyIterator(list)
	if s := it.String(); s != "$(#1)" {
		t.Errorf("expected $(#1), got %s", s)
	}
}

func TestHasOperation(t *testing.T) {

	list := newListA("a", "b", "c", "d")
	it := NewListIterator(list, []any{1, 3, 1})
	hasOp := it.HasOperation("reset")
	if !hasOp {
		t.Errorf("HasOperation(reset) must be true, got false")
	}
}

func TestCallOperationReset(t *testing.T) {

	list := newListA("a", "b", "c", "d")
	it := NewListIterator(list, []any{1, 3, 1})
	if v, err := it.CallOperation("reset", nil); err != nil {
		t.Errorf("Error on CallOperation(reset): %v", err)
	} else {
		t.Logf("Reset result: %v", v)
	}
}

func TestCallOperationIndex(t *testing.T) {

	list := newListA("a", "b", "c", "d")
	it := NewListIterator(list, []any{1, 3, 1})
	if v, err := it.CallOperation("index", nil); err != nil {
		t.Errorf("Error on CallOperation(index): %v", err)
	} else {
		t.Logf("Index result: %v", v)
	}
}

func TestCallOperationCount(t *testing.T) {

	list := newListA("a", "b", "c", "d")
	it := NewListIterator(list, []any{1, 3, 1})
	if v, err := it.CallOperation("count", nil); err != nil {
		t.Errorf("Error on CallOperation(count): %v", err)
	} else {
		t.Logf("Count result: %v", v)
	}
}

func TestCallOperationUnknown(t *testing.T) {

	list := newListA("a", "b", "c", "d")
	it := NewListIterator(list, []any{1, 3, 1})
	if v, err := it.CallOperation("unknown", nil); err == nil {
		t.Errorf("Expected error on CallOperation(unknown), got %v", v)
	}
}