import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertThrows;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;

import org.junit.jupiter.api.Test;

class NumberRangeTest {

    private static List<Integer> collect(Iterable<Integer> numbers) {
        List<Integer> out = new ArrayList<>();
        for (int n : numbers) {
            out.add(n);
        }
        return out;
    }

    @Test
    void forEachVisitsEveryStep() {
        assertEquals(List.of(0, 3, 6, 9), collect(new NumberRange(0, 10, 3)));
    }

    @Test
    void emptyRangeHasNoElements() {
        Iterator<Integer> it = new NumberRange(5, 5, 1).iterator();
        assertFalse(it.hasNext());
        assertThrows(NoSuchElementException.class, () -> it.next());
    }

    @Test
    void eachIteratorHasItsOwnCursor() {
        NumberRange r = new NumberRange(1, 4, 1);
        Iterator<Integer> a = r.iterator();
        a.next();
        Iterator<Integer> b = r.iterator();
        assertEquals(2, a.next());
        assertEquals(1, b.next());
    }

    @Test
    void stepMustBePositive() {
        assertThrows(IllegalArgumentException.class, () -> new NumberRange(0, 10, 0));
    }
}
