// Path: src/main/java/factoryduke/generators/Generators.java
// public final class Generators {
// 	private Generators() {
// 	}
// 
// 	public static SequenceGenerator sequence() {
// 		return new SequenceGenerator();
// 	}
// 
// 	public static StringSequenceGenerator stringSequence(String prefix) {
// 		Assert.that().notNull(prefix, "prefix may not be null");
// 		return new StringSequenceGenerator(prefix);
// 	}
// 
// 	public static DateGenerator dateSequence() {
// 		return new DateGenerator();
// 	}
// 
// 	public static <T> Generator<T> constant(final T constant) {
// 		return values(constant);
// 	}
// 
// 	public static <T> SequenceValuesGenerator<T> values(T...values){
// 		return new SequenceValuesGenerator().withValues(values);
// 	}
// 
// 	public static <T> RandomValuesGenerator<T> random(T...values){
// 		return new RandomValuesGenerator<>().withValues(values);
// 	}
// }
// 
// Path: src/main/java/factoryduke/generators/SequenceValuesGenerator.java
// public class SequenceValuesGenerator<T> implements Generator<T> {
// 
// 	protected List<T> actual;
// 
// 	private AtomicInteger counter;
// 
// 	SequenceValuesGenerator(){
// 		this(new ArrayList<>());
// 	}
// 
// 	private SequenceValuesGenerator(List<T> values) {
// 		this.actual = values;
// 		counter = new AtomicInteger();
// 	}
// 
// 	public SequenceValuesGenerator withValues(T... values){
// 		Assert.that().notNull(values).isTrue(values.length > 0);
// 
// 		for(T v : values){
// 			this.actual.add(v);
// 		}
// 
// 		return this;
// 	}
// 
// 	@Override
// 	public T nextValue() {
// 		T value = actual.isEmpty() ? null : actual.get(counter.getAndIncrement());
// 
// 		if(isloopFinished()){
// 			counter = new AtomicInteger();
// 		}
// 
// 		return value;
// 	}
// 
// 	protected boolean isloopFinished() {
// 		return actual.size() == counter.intValue();
// 	}
// }
// 
// Path: src/test/java/model/Address.java
// public class Address {
// 	private String country;
// 	private String street;
// 	private String city;
// 
// 	public String getCountry() {
// 		return country;
// 	}
// 
// 	public void setCountry(String country) {
// 		this.country = country;
// 	}
// 
// 	public String getCity() {
// 		return city;
// 	}
// 
// 	public void setCity(String city) {
// 		this.city = city;
// 	}
// 
// 	public String getStreet() {
// 		return street;
// 	}
// 
// 	public void setStreet(String street) {
// 		this.street = street;
// 	}
// }
// 
// Path: src/test/java/model/Role.java
// public enum Role {
// 	ADMIN, USER
// }
// 
// Path: src/test/java/model/User.java
// public class User {
// 	private long id;
// 	private String name;
// 	private String lastName;
// 	private Role role;
// 
// 	public long getId() {
// 		return id;
// 	}
// 
// 	public void setId(long id) {
// 		this.id = id;
// 	}
// 
// 	private Address addr;
// 
// 	public Role getRole() {
// 		return role;
// 	}
// 
// 	public void setRole(Role role) {
// 		this.role = role;
// 	}
// 
// 	public void setAddr(Address addr) {
// 		this.addr = addr;
// 	}
// 
// 	public void setLastName(String lastName) {
// 		this.lastName = lastName;
// 	}
// 
// 	public void setName(String name) {
// 		this.name = name;
// 	}
// 
// 	public Address getAddr() {
// 		return addr;
// 	}
// 
// 	public String getLastName() {
// 		return lastName;
// 	}
// 
// 	public String getName() {
// 		return name;
// 	}
// }


import factoryduke.generators.Generators;
import factoryduke.generators.SequenceValuesGenerator;
import model.Address;
import model.Role;
import model.User;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.tuple;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
	@Test
	public void defaultUserWithAddrWithOverride(){
		User user = FactoryDuke.build(User.class, "user_with_fr_address").toOne();
		assertThat(user).isNotNull().hasFieldOrPropertyWithValue("addr.city", "Paris");
	}

	@Test
	public void adminUserWithFrAddr(){
		User user = FactoryDuke.build(User.class, "user_with_fr_address", u -> u.setRole(Role.ADMIN)).toOne();

		assertThat(user).isNotNull()
				.hasFieldOrPropertyWithValue("role", Role.ADMIN)
				.hasFieldOrPropertyWithValue("addr.city", "Paris");
	}

	@Test
	public void repeat_with_generators(){
		FactoryDuke.reset();

		SequenceValuesGenerator<Long> ids = Generators.values(1L, 2L, 3L);
		SequenceValuesGenerator<String> names = Generators.values("Scott", "John", "Malcom");

		FactoryDuke.define(User.class, u -> {
			u.setId(ids.nextValue());
			u.setName(names.nextValue());
		});

		List<User> users = FactoryDuke.build(User.class).times(3).toList();

		assertThat(users).hasSize(3).extracting(User::getId, User::getName)
// Path: src/main/java/factoryduke/generators/Generators.java
// public final class Generators {
// 	private Generators() {
// 	}
// 
// 	public static SequenceGenerator sequence() {
// 		return new SequenceGenerator();
// 	}
// 
// 	public static StringSequenceGenerator stringSequence(String prefix) {
// 		Assert.that().notNull(prefix, "prefix may not be null");
// 		return new StringSequenceGenerator(prefix);
// 	}
// 
// 	public static DateGenerator dateSequence() {
// 		return new DateGenerator();
// 	}
// 
// 	public static <T> Generator<T> constant(final T constant) {
// 		return values(constant);
// 	}
// 
// 	public static <T> SequenceValuesGenerator<T> values(T...values){
// 		return new SequenceValuesGenerator().withValues(values);
// 	}
// 
// 	public static <T> RandomValuesGenerator<T> random(T...values){
// 		return new RandomValuesGenerator<>().withValues(values);
// 	}
// }
// 
// Path: src/main/java/factoryduke/generators/SequenceValuesGenerator.java
// public class SequenceValuesGenerator<T> implements Generator<T> {
// 
// 	protected List<T> actual;
// 
// 	private AtomicInteger counter;
// 
// 	SequenceValuesGenerator(){
// 		this(new ArrayList<>());
// 	}
// 
// 	private SequenceValuesGenerator(List<T> values) {
// 		this.actual = values;
// 		counter = new AtomicInteger();
// 	}
// 
// 	public SequenceValuesGenerator withValues(T... values){
// 		Assert.that().notNull(values).isTrue(values.length > 0);
// 
// 		for(T v : values){
// 			this.actual.add(v);
// 		}
// 
// 		return this;
// 	}
// 
// 	@Override
// 	public T nextValue() {
// 		T value = actual.isEmpty() ? null : actual.get(counter.getAndIncrement());
// 
// 		if(isloopFinished()){
// 			counter = new AtomicInteger();
// 		}
// 
// 		return value;
// 	}
// 
// 	protected boolean isloopFinished() {
// 		return actual.size() == counter.intValue();
// 	}
// }
// 
// Path: src/test/java/model/Address.java
// public class Address {
// 	private String country;
// 	private String street;
// 	private String city;
// 
// 	public String getCountry() {
// 		return country;
// 	}
// 
// 	public void setCountry(String country) {
// 		this.country = country;
// 	}
// 
// 	public String getCity() {
// 		return city;
// 	}
// 
// 	public void setCity(String city) {
// 		this.city = city;
// 	}
// 
// 	public String getStreet() {
// 		return street;
// 	}
// 
// 	public void setStreet(String street) {
// 		this.street = street;
// 	}
// }
// 
// Path: src/test/java/model/Role.java
// public enum Role {
// 	ADMIN, USER
// }
// 
// Path: src/test/java/model/User.java
// public class User {
// 	private long id;
// 	private String name;
// 	private String lastName;
// 	private Role role;
// 
// 	public long getId() {
// 		return id;
// 	}
// 
// 	public void setId(long id) {
// 		this.id = id;
// 	}
// 
// 	private Address addr;
// 
// 	public Role getRole() {
// 		return role;
// 	}
// 
// 	public void setRole(Role role) {
// 		this.role = role;
// 	}
// 
// 	public void setAddr(Address addr) {
// 		this.addr = addr;
// 	}
// 
// 	public void setLastName(String lastName) {
// 		this.lastName = lastName;
// 	}
// 
// 	public void setName(String name) {
// 		this.name = name;
// 	}
// 
// 	public Address getAddr() {
// 		return addr;
// 	}
// 
// 	public String getLastName() {
// 		return lastName;
// 	}
// 
// 	public String getName() {
// 		return name;
// 	}
// }


// Path: src/test/java/factoryduke/ManualFactoryDukeTest.java
import factoryduke.generators.Generators;
import factoryduke.generators.SequenceValuesGenerator;
import model.Address;
import model.Role;
import model.User;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.tuple;
import java.util.List;
import org.junit.Before;
import org.junit.Test;

	@Test
	public void defaultUserWithAddrWithOverride(){
		User user = FactoryDuke.build(User.class, "user_with_fr_address").toOne();
		assertThat(user).isNotNull().hasFieldOrPropertyWithValue("addr.city", "Paris");
	}

	@Test
	public void adminUserWithFrAddr(){
		User user = FactoryDuke.build(User.class, "user_with_fr_address", u -> u.setRole(Role.ADMIN)).toOne();

		assertThat(user).isNotNull()
				.hasFieldOrPropertyWithValue("role", Role.ADMIN)
				.hasFieldOrPropertyWithValue("addr.city", "Paris");
	}

	@Test
	public void repeat_with_generators(){
		FactoryDuke.reset();

		SequenceValuesGenerator<Long> ids = Generators.values(1L, 2L, 3L);
		SequenceValuesGenerator<String> names = Generators.values("Scott", "John", "Malcom");

		FactoryDuke.define(User.class, u -> {
			u.setId(ids.nextValue());
			u.setName(names.nextValue());
		});

		List<User> users = FactoryDuke.build(User.class).times(3).toList();

		assertThat(users).hasSize(3).extracting(User::getId, User::getName)
				.containsExactly(tuple(1L, "Scott"), tuple(2L, "John"), tuple(3L, "Malcom"));