Solucionado (ver solução)
Solucionado
(ver solução)
1
resposta

Verificação dos itens da lista de lances

Fiz a implementação usando TDD, mas vendo a resposta vi que nem todos os itens da lista foram verificados, apenas o último. Em listas grandes essa é uma boa prática ou devemos ver todos os itens.

Segue o código realizado.

package br.com.caelum.leilao.dominio;

import java.util.Collections;
import java.util.List;
import java.util.Optional;

import com.google.common.collect.Lists;

public class Leilao {
    private String descricao;
    private List<Lance> lances;

    public Leilao(String descricao) {
        this.descricao = descricao;
        this.lances = Lists.newArrayList();
    }

    public void propoe(Lance lance) {        

        if(isRegrasValidasDo(lance)){
            lances.add(lance);
            Collections.sort(lances);
        }
    }

    private boolean isRegrasValidasDo(Lance lance) {
        return lances.isEmpty() || isUsuarioUltimoLanceDiferenteDoAtual(lance) && isUsuarioLanceAtualJaDeuMenos5LancesComputados(lance);
    }

    private boolean isUsuarioLanceAtualJaDeuMenos5LancesComputados(Lance lance) {
        return lances.stream().filter(l-> l.getUsuario().equals(lance.getUsuario())).count() < 5;
    }

    private boolean isUsuarioUltimoLanceDiferenteDoAtual(Lance lance) {
        return getUltimoUsuario()
            .filter(ultimoUsuario-> !ultimoUsuario.equals(lance.getUsuario()))
            .isPresent();
    }

    private Optional<Usuario> getUltimoUsuario() {

        if(lances.isEmpty()){
            return Optional.empty();
        }

        return Optional.of(lances.get(lances.size()-1).getUsuario());
    }

    public String getDescricao() {
        return descricao;
    }

    public EstatisticasDoLeilao getEstatiscasDoLeilao() {
        return new EstatisticasDoLeilao(this);
    }

    public List<Lance> getLances() {
        return Collections.unmodifiableList(lances);
    }

    @Override
    public String toString() {
        return String.format("Leilao [descricao=%s, lances=%s]", descricao, lances);
    }
}

package br.com.caelum.leilao.dominio;

import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.hasProperty;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;

import org.junit.Test;

@SuppressWarnings("unchecked")
public class LeilaoTest {

    @Test
    public void naoDeveAceitarDoisLancesSeguidosDoMesmoUsuario(){
        Usuario paulo = new Usuario("Paulo");

        Leilao leilao = LeilaoDataBuilder.builder()
            .com("Macbook Air Pro 15")
            .comLanceDe(1_000, paulo)
            .comLanceDe(2_000, new Usuario("Joana"))
            .comLanceDe(3_000, paulo)
            .comLanceDe(4_000, paulo)
            .build();

        assertThat(leilao.getLances(), hasSize(3));
        assertThat(leilao.getLances(), contains(hasProperty("valor", is(1000.0)), hasProperty("valor", is(2000.0)), hasProperty("valor", is(3000.0))));
    }

    @Test
    public void naoDeveAceitarMaisDoQue5LancesDeUmMesmoUsuario(){
        Usuario paulo = new Usuario("Paulo");
        Usuario joana = new Usuario("Joana");

        Leilao leilao = LeilaoDataBuilder.builder()
            .com("Macbook Air Pro 15")
            .comLanceDe(1_000, paulo)
            .comLanceDe(2_000, joana)
            .comLanceDe(3_000, paulo)
            .comLanceDe(4_000, joana)
            .comLanceDe(5_000, paulo)
            .comLanceDe(6_000, joana)
            .comLanceDe(7_000, paulo)
            .comLanceDe(8_000, joana)
            .comLanceDe(9_000, paulo)
            .comLanceDe(10_000, joana)
            .comLanceDe(11_000, paulo)
            .build();

        assertThat(leilao.getLances(), hasSize(10));
        assertThat(leilao.getLances(), contains(hasProperty("valor", is(1_000.0)), hasProperty("valor", is(2_000.0)), hasProperty("valor", is(3_000.0)), hasProperty("valor", is(4_000.0)), hasProperty("valor", is(5_000.0)),
                hasProperty("valor", is(6_000.0)), hasProperty("valor", is(7_000.0)), hasProperty("valor", is(8_000.0)), hasProperty("valor", is(9_000.0)), hasProperty("valor", is(10_000.0))));
    }
}

package br.com.caelum.leilao.dominio;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.IntStream;

public class LeilaoDataBuilder {
    private String nomeLeilao = "Playstation 4";
    private Ordem ordem;
    private int numeroLances;
    private List<Lance> lances = new ArrayList<>(); 

    public LeilaoDataBuilder com(String nome){
        this.nomeLeilao = nome;

        return this;
    }

    public LeilaoDataBuilder comLancesAutomaticosNaOrdem(int numeroLances, Ordem ordem){
        this.numeroLances = numeroLances;
        this.ordem = ordem;

        return this;
    }

    public LeilaoDataBuilder comLanceDe(double valorLance, Usuario usuario){
        this.lances.add(new Lance(usuario, valorLance));

        return this;
    }

    public static LeilaoDataBuilder builder(){
        return new LeilaoDataBuilder();
    }

    public Leilao build() {
        Leilao leilao = new Leilao(nomeLeilao);

        if(!lances.isEmpty()){
            lances.forEach(leilao::propoe);

        }else{
            IntStream.range(0, numeroLances)
                .mapToObj(i -> new Lance(new Usuario("Fulano " + i), ordem.proximoNumero(i)))
                .forEach(l -> leilao.propoe(l));    
        }

        return leilao;
    }

    public enum Ordem{
        CRESCENTE(1,1), DECRESCENTE(999_999, -1);

        private int numeroBase;
        private int numeroSinal;

        private Ordem(int numeroBase, int numeroSinal) {
            this.numeroBase = numeroBase;
            this.numeroSinal = numeroSinal;
        }

        public int proximoNumero(int numeroIteracao) {
            return numeroBase + (numeroIteracao * numeroSinal);
        }
    }
}
1 resposta
solução!

A boa prática pede para verificar todos os itens da sua lista... esse é um erro que vc não quer ter no seu teste :).