import "copyright.stg"
import "primitiveEquals.stg"
import "primitiveHashCode.stg"
import "primitiveLiteral.stg"

isTest() ::= "true"

targetPath() ::= "org/eclipse/collections/impl/lazy/primitive"

fileName(primitive) ::= "Select<primitive.name>IterableTest"

class(primitive) ::= <<
<body(primitive.type, primitive.name, primitive.wrapperName)>
>>

body(type, name, wrapperName) ::= <<
<copyright()>

package org.eclipse.collections.impl.lazy.primitive;

import java.util.NoSuchElementException;

import org.eclipse.collections.api.Lazy<name>Iterable;
import org.eclipse.collections.api.iterator.<name>Iterator;
import org.eclipse.collections.impl.bag.mutable.primitive.<name>HashBag;
import org.eclipse.collections.impl.block.factory.primitive.<name>Predicates;
<if(primitive.floatingPoint)>import org.eclipse.collections.impl.list.Interval;<endif>
import org.eclipse.collections.impl.list.mutable.primitive.<name>ArrayList;
import org.eclipse.collections.impl.math.Mutable<wrapperName>;
import org.eclipse.collections.impl.set.mutable.primitive.<name>HashSet;
import org.eclipse.collections.impl.test.Verify;
import org.junit.Assert;
import org.junit.Test;

/**
 * JUnit test for {@link Select<name>Iterable}.
 * This file was automatically generated from template file primitiveSelectIterableTest.stg.
 */
public class Select<name>IterableTest
{
    private final Select<name>Iterable iterable =
            new Select<name>Iterable(<name>ArrayList.newListWith(<["1", "2", "3", "4", "5"]:(literal.(type))(); separator=", ">), <name>Predicates.lessThan(<(literal.(type))("3")>));

    @Test
    public void <type>Iterator()
    {
        <wideType.(type)> sum = <wideZero.(type)>;
        for (<name>Iterator iterator = this.iterable.<type>Iterator(); iterator.hasNext(); )
        {
            sum += iterator.next();
        }
        Assert.assertEquals(<(wideLiteral.(type))("3")>, sum<(wideDelta.(type))>);
    }

    @Test
    public void forEach()
    {
        <wideType.(type)>[] sum = new <wideType.(type)>[1];
        this.iterable.forEach((<type> each) -> sum[0] += each);
        Assert.assertEquals(<(wideLiteral.(type))("3")>, sum[0]<(wideDelta.(type))>);
    }

    @Test
    public void size()
    {
        Verify.assertSize(2, this.iterable);
    }

    @Test
    public void empty()
    {
        Assert.assertTrue(this.iterable.notEmpty());
        Verify.assertNotEmpty(this.iterable);
    }

    @Test
    public void count()
    {
        Assert.assertEquals(1L, this.iterable.count(<name>Predicates.lessThan(<(literal.(type))("2")>)));
        Assert.assertEquals(0L, this.iterable.count(<name>Predicates.lessThan(<(literal.(type))("0")>)));
    }

    @Test
    public void anySatisfy()
    {
        Assert.assertTrue(this.iterable.anySatisfy(<name>Predicates.lessThan(<(literal.(type))("2")>)));
        Assert.assertFalse(this.iterable.anySatisfy(<name>Predicates.greaterThan(<(literal.(type))("4")>)));
    }

    @Test
    public void allSatisfy()
    {
        Assert.assertTrue(this.iterable.allSatisfy(<name>Predicates.greaterThan(<(literal.(type))("0")>)));
        Assert.assertFalse(this.iterable.allSatisfy(<name>Predicates.lessThan(<(literal.(type))("2")>)));
        Assert.assertFalse(this.iterable.allSatisfy(<name>Predicates.lessThan(<(literal.(type))("1")>)));
        Assert.assertTrue(this.iterable.allSatisfy(<name>Predicates.lessThan(<(literal.(type))("4")>)));
    }

    @Test
    public void noneSatisfy()
    {
        Assert.assertTrue(this.iterable.noneSatisfy(<name>Predicates.lessThan(<(literal.(type))("0")>)));
        Assert.assertFalse(this.iterable.noneSatisfy(<name>Predicates.lessThan(<(literal.(type))("2")>)));
        Assert.assertTrue(this.iterable.noneSatisfy(<name>Predicates.lessThan(<(literal.(type))("1")>)));
        Assert.assertTrue(this.iterable.noneSatisfy(<name>Predicates.greaterThan(<(literal.(type))("4")>)));
    }

    @Test
    public void select()
    {
        Verify.assertSize(1, this.iterable.select(<name>Predicates.greaterThan(<(literal.(type))("1")>)));
        Verify.assertSize(0, this.iterable.select(<name>Predicates.lessThan(<(literal.(type))("0")>)));
    }

    @Test
    public void reject()
    {
        Verify.assertSize(1, this.iterable.reject(<name>Predicates.greaterThan(<(literal.(type))("1")>)));
        Verify.assertSize(0, this.iterable.reject(<name>Predicates.greaterThan(<(literal.(type))("0")>)));
    }

    @Test
    public void detectIfNone()
    {
        Assert.assertEquals(<(wideLiteral.(type))("1")>, this.iterable.detectIfNone(<name>Predicates.lessThan(<(literal.(type))("4")>), <(literal.(type))("0")>)<(wideDelta.(type))>);
        Assert.assertEquals(<(wideLiteral.(type))("0")>, this.iterable.detectIfNone(<name>Predicates.greaterThan(<(literal.(type))("3")>), <(literal.(type))("0")>)<(wideDelta.(type))>);
    }

    @Test
    public void collect()
    {
        Verify.assertIterableSize(2, this.iterable.collect(String::valueOf));
    }

    @Test
    public void sum()
    {
        Assert.assertEquals(<(wideLiteral.(type))("3")>, this.iterable.sum()<(wideDelta.(type))>);
    }

    <if(primitive.floatPrimitive)>@Test
public void sumConsistentRounding()
{
    <name>ArrayList list = <name>ArrayList.newListWith(
            Interval.oneTo(100_000)
                    .toList()
                    .shuffleThis()
                    .collect<name>(i -> 1.0f / (i.floatValue() * i.floatValue() * i.floatValue() * i.floatValue()))
                    .toArray());
    Select<name>Iterable iterable = new Select<name>Iterable(list, <name>Predicates.alwaysTrue());

    // The test only ensures the consistency/stability of rounding. This is not meant to test the "correctness" of the float calculation result.
    // Indeed the lower bits of this calculation result are always incorrect due to the information loss of original float values.
    Assert.assertEquals(
            1.082323233761663,
            iterable.sum(),
            1.0e-15);
}

    <elseif(primitive.doublePrimitive)>@Test
public void sumConsistentRounding()
{
    <name>ArrayList list = <name>ArrayList.newListWith(
            Interval.oneTo(100_000)
                    .toList()
                    .shuffleThis()
                    .collect<name>(i -> <["1.0"]:(decimalLiteral.(type))()> / (i.<type>Value() * i.<type>Value() * i.<type>Value() * i.<type>Value()))
                    .toArray());
    Select<name>Iterable iterable = new Select<name>Iterable(list, <name>Predicates.alwaysTrue());

    Assert.assertEquals(
            1.082323233711138,
            iterable.sum(),
            1.0e-15);
}

    <endif>
    @Test
    public void max()
    {
        Assert.assertEquals(<(literal.(type))("2")>, this.iterable.max()<(wideDelta.(type))>);
    }

    @Test
    public void min()
    {
        Assert.assertEquals(<(literal.(type))("1")>, this.iterable.min()<(wideDelta.(type))>);
    }

    @Test
    public void minIfEmpty()
    {
        Assert.assertEquals(<(literal.(type))("1")>, this.iterable.minIfEmpty(<(literal.(type))("0")>)<(wideDelta.(type))>);
        Assert.assertEquals(
                <(literal.(type))("0")>,
                this.iterable.select(<name>Predicates.lessThan(<(literal.(type))("0")>)).minIfEmpty(<(literal.(type))("0")>)<(wideDelta.(type))>);
    }

    @Test
    public void maxIfEmpty()
    {
        Assert.assertEquals(<(literal.(type))("2")>, this.iterable.maxIfEmpty(<(literal.(type))("0")>)<(wideDelta.(type))>);
        Assert.assertEquals(
                <(literal.(type))("0")>,
                this.iterable.select(<name>Predicates.lessThan(<(literal.(type))("0")>)).maxIfEmpty(<(literal.(type))("0")>)<(wideDelta.(type))>);
    }

    @Test(expected = NoSuchElementException.class)
    public void maxThrowsOnEmpty()
    {
        new Select<name>Iterable(new <name>ArrayList(), <name>Predicates.lessThan(<(literal.(type))("3")>)).max();
    }

    @Test(expected = NoSuchElementException.class)
    public void minThrowsOnEmpty()
    {
        new Select<name>Iterable(new <name>ArrayList(), <name>Predicates.lessThan(<(literal.(type))("3")>)).min();
    }

    @Test
    public void average()
    {
        Assert.assertEquals(1.5d, this.iterable.average(), 0.0);
    }

    @Test(expected = ArithmeticException.class)
    public void averageThrowsOnEmpty()
    {
        new Select<name>Iterable(new <name>ArrayList(), <name>Predicates.lessThan(<(literal.(type))("3")>)).average();
    }

    @Test
    public void median()
    {
        Assert.assertEquals(1.5d, this.iterable.median(), 0.0);
    }

    @Test(expected = ArithmeticException.class)
    public void medianThrowsOnEmpty()
    {
        new Select<name>Iterable(new <name>ArrayList(), <name>Predicates.lessThan(<(literal.(type))("3")>)).median();
    }

    @Test
    public void toArray()
    {
        Assert.assertArrayEquals(new <type>[]{1, 2}, this.iterable.toArray()<(delta.(type))>);
    }

    @Test
    public void contains()
    {
        Assert.assertTrue(this.iterable.contains(<(literal.(type))("1")>));
        Assert.assertTrue(this.iterable.contains(<(literal.(type))("2")>));
        Assert.assertFalse(this.iterable.contains(<(literal.(type))("3")>));
    }

    @Test
    public void containsAllArray()
    {
        Assert.assertTrue(this.iterable.containsAll(<["1"]:(literal.(type))(); separator=", ">));
        Assert.assertTrue(this.iterable.containsAll(<["2"]:(literal.(type))(); separator=", ">));
        Assert.assertTrue(this.iterable.containsAll(<["1", "2"]:(literal.(type))(); separator=", ">));
        Assert.assertFalse(this.iterable.containsAll(<["1", "2", "3"]:(literal.(type))(); separator=", ">));
        Assert.assertFalse(this.iterable.containsAll(<["4", "5", "6"]:(literal.(type))(); separator=", ">));
    }

    @Test
    public void containsAllIterable()
    {
        Assert.assertTrue(this.iterable.containsAll(<name>ArrayList.newListWith(<["1"]:(literal.(type))(); separator=", ">)));
        Assert.assertTrue(this.iterable.containsAll(<name>ArrayList.newListWith(<["2"]:(literal.(type))(); separator=", ">)));
        Assert.assertTrue(this.iterable.containsAll(<name>ArrayList.newListWith(<["1", "2"]:(literal.(type))(); separator=", ">)));
        Assert.assertFalse(this.iterable.containsAll(<name>ArrayList.newListWith(<["1", "2", "3"]:(literal.(type))(); separator=", ">)));
        Assert.assertFalse(this.iterable.containsAll(<name>ArrayList.newListWith(<["4", "5", "6"]:(literal.(type))(); separator=", ">)));
    }

    @Test
    public void toSortedArray()
    {
        Assert.assertArrayEquals(new <type>[]{1, 2}, this.iterable.toSortedArray()<(delta.(type))>);
    }

    @Test
    public void toList()
    {
        Assert.assertEquals(<name>ArrayList.newListWith(<["1", "2"]:(literal.(type))(); separator=", ">), this.iterable.toList());
    }

    @Test
    public void toSortedList()
    {
        Assert.assertEquals(<name>ArrayList.newListWith(<["1", "2"]:(literal.(type))(); separator=", ">), this.iterable.toSortedList());
    }

    @Test
    public void toSet()
    {
        Assert.assertEquals(<name>HashSet.newSetWith(<["1", "2"]:(literal.(type))(); separator=", ">), this.iterable.toSet());
    }

    @Test
    public void toBag()
    {
        Assert.assertEquals(<name>HashBag.newBagWith(<["1", "2"]:(literal.(type))(); separator=", ">), this.iterable.toBag());
    }

    @Test
    public void asLazy()
    {
        Assert.assertEquals(this.iterable.toSet(), this.iterable.asLazy().toSet());
        Verify.assertInstanceOf(Lazy<name>Iterable.class, this.iterable.asLazy());
        Assert.assertSame(this.iterable, this.iterable.asLazy());
    }

    @Test
    public void injectInto()
    {
        Mutable<wrapperName> result = this.iterable.injectInto(new Mutable<wrapperName>(<(literal.(type))("0")>), Mutable<wrapperName>::add);
        Assert.assertEquals(new Mutable<wrapperName>(<(literal.(type))("3")>), result);
    }
}

>>
