Permalink
Browse files

support to circular reference to association of models

  • Loading branch information...
1 parent 7cf4578 commit 97a9ed9d55f76e957489ac02d66ff8aa459c8714 @douglasrodrigo douglasrodrigo committed Dec 5, 2011
@@ -1,6 +1,8 @@
package br.com.fixturefactory;
+import br.com.fixturefactory.function.AtomicFunction;
import br.com.fixturefactory.function.Function;
+import br.com.fixturefactory.function.RelationFunction;
public class Property {
@@ -25,7 +27,16 @@ public String getName() {
}
public Object getValue() {
- return this.value == null ? this.function.generateValue() : this.value;
+ return this.value == null ? ((AtomicFunction) this.function).generateValue() : this.value;
+ }
+
+ public Object getValue(Object owner) {
+ return ((RelationFunction) this.function).generateValue(owner);
+ }
+
+
+ public boolean hasRelationFunction() {
+ return this.function instanceof RelationFunction;
}
}
@@ -19,6 +19,7 @@
import br.com.fixturefactory.base.Interval;
import br.com.fixturefactory.base.Range;
import br.com.fixturefactory.base.Sequence;
+import br.com.fixturefactory.function.AssociationFunction;
import br.com.fixturefactory.function.ChronicFunction;
import br.com.fixturefactory.function.DateTimeFunction;
import br.com.fixturefactory.function.FixtureFunction;
@@ -49,6 +50,15 @@ public Function fixture(Class<?> clazz, Integer quantity, String label) {
return new FixtureFunction(clazz, label, quantity);
}
+ public Function association(Class<?> clazz, String label, String targetAttribute) {
+ return new AssociationFunction(new FixtureFunction(clazz, label), targetAttribute);
+ }
+
+ public Function association(Class<?> clazz, Integer quantity, String label, String targetAttribute) {
+ return new AssociationFunction(new FixtureFunction(clazz, label, quantity), targetAttribute);
+ }
+
+
public Function random(Class<?> clazz, Object... dataset) {
return new RandomFunction(clazz, dataset);
}
@@ -66,7 +66,7 @@ private Object createObject(Rule rule) {
Object result = ReflectionUtils.newInstance(this.clazz);
for (Property property : rule.getProperties()) {
- Object value = property.getValue();
+ Object value = property.hasRelationFunction() ? property.getValue(result) : property.getValue();
if (value instanceof String) {
String baseValue = (String) value;
@@ -0,0 +1,35 @@
+package br.com.fixturefactory.function;
+
+import java.util.Collection;
+
+import br.com.fixturefactory.util.ReflectionUtils;
+
+public class AssociationFunction implements RelationFunction {
+
+ private FixtureFunction fixtureFunction;
+
+ private String targetAttribute;
+
+ public AssociationFunction(FixtureFunction fixtureFunction, String targetAttribute) {
+ this.fixtureFunction = fixtureFunction;
+ this.targetAttribute = targetAttribute;
+ }
+
+ @Override
+ public <T> T generateValue(Object owner) {
+ Object target = fixtureFunction.generateValue();
+
+ if (target instanceof Collection<?>) {
+ for (Object item : (Collection<?>) target) {
+ ReflectionUtils.invokeRecursiveSetter(item, targetAttribute, owner);
+ }
+ } else {
+ ReflectionUtils.invokeRecursiveSetter(target, targetAttribute, owner);
+ }
+
+ return (T) target;
+ }
+
+
+
+}
@@ -0,0 +1,7 @@
+package br.com.fixturefactory.function;
+
+public interface AtomicFunction extends Function {
+
+ <T> T generateValue();
+
+}
@@ -4,7 +4,7 @@
import com.mdimension.jchronic.Options;
import com.mdimension.jchronic.utils.Span;
-public class ChronicFunction implements Function {
+public class ChronicFunction implements AtomicFunction {
private String dateText;
@@ -2,7 +2,7 @@
import br.com.fixturefactory.base.Range;
-public class CpfFunction implements Function {
+public class CpfFunction implements AtomicFunction {
private boolean formatted;
@@ -4,7 +4,7 @@
import br.com.fixturefactory.base.Range;
-public class DateTimeFunction implements Function {
+public class DateTimeFunction implements AtomicFunction {
private RandomFunction random;
@@ -3,7 +3,7 @@
import br.com.fixturefactory.Fixture;
import br.com.fixturefactory.TemplateHolder;
-public class FixtureFunction implements Function {
+public class FixtureFunction implements AtomicFunction {
private Class<?> clazz;
@@ -2,6 +2,5 @@
public interface Function {
- <T> T generateValue();
}
@@ -3,7 +3,7 @@
import br.com.bfgex.Gender;
import br.com.bfgex.RandomGen;
-public class NameFunction implements Function {
+public class NameFunction implements AtomicFunction {
private Gender gender;
@@ -4,13 +4,13 @@
import br.com.fixturefactory.base.Range;
-public class RandomFunction implements Function {
+public class RandomFunction implements AtomicFunction {
private Class<?> type;
private Object[] dataset;
- private Function[] functions;
+ private AtomicFunction[] functions;
private Range range;
@@ -22,7 +22,7 @@ public RandomFunction(Object[] dataset) {
this.dataset = dataset;
}
- public RandomFunction(Function[] functions) {
+ public RandomFunction(AtomicFunction[] functions) {
this.functions = functions;
}
@@ -2,7 +2,7 @@
import br.com.bfgex.RegexGen;
-public class RegexFunction implements Function {
+public class RegexFunction implements AtomicFunction {
private String pattern;
@@ -0,0 +1,7 @@
+package br.com.fixturefactory.function;
+
+public interface RelationFunction extends Function {
+
+ <T> T generateValue(Object owner);
+
+}
@@ -2,7 +2,7 @@
import br.com.fixturefactory.base.Sequence;
-public class SequenceFunction implements Function {
+public class SequenceFunction implements AtomicFunction {
private Sequence<?> sequence;
@@ -0,0 +1,42 @@
+package br.com.fixturefactory;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import br.com.fixturefactory.model.Item;
+import br.com.fixturefactory.model.Order;
+import br.com.fixturefactory.model.Payment;
+
+public class FixtureCircularReferenceTest {
+
+ @Before
+ public void setUp() {
+ Fixture.of(Order.class).addTemplate("valid", new Rule(){{
+ add("id", random(Long.class, range(1L, 200L)));
+ add("items", association(Item.class, 3, "valid", "order"));
+ add("payment", association(Payment.class, "valid", "order"));
+ }});
+
+ Fixture.of(Item.class).addTemplate("valid", new Rule(){{
+ add("productId", random(Integer.class, range(1L, 200L)));
+ }});
+
+ Fixture.of(Payment.class).addTemplate("valid", new Rule(){{
+ add("id", random(Long.class, range(1L, 200L)));
+ }});
+
+ }
+
+ @Test
+ public void circularReference() {
+ Order order = Fixture.of(Order.class).gimme("valid");
+
+ for (Item item : order.getItems()) {
+ Assert.assertTrue("order relationship with item should have the same reference", item.getOrder() == order);
+ }
+
+ Assert.assertTrue("payment one-to-one relationship should have the same reference", order == order.getPayment().getOrder());
+ }
+
+}
@@ -0,0 +1,28 @@
+package br.com.fixturefactory.model;
+
+import java.io.Serializable;
+
+public class Item implements Serializable {
+
+ private static final long serialVersionUID = -8679257032342835407L;
+
+ private Order order;
+
+ private Integer productId;
+
+ public Order getOrder() {
+ return order;
+ }
+
+ public void setOrder(Order order) {
+ this.order = order;
+ }
+
+ public Integer getProductId() {
+ return productId;
+ }
+
+ public void setProductId(Integer productId) {
+ this.productId = productId;
+ }
+}
@@ -0,0 +1,40 @@
+package br.com.fixturefactory.model;
+
+import java.io.Serializable;
+import java.util.List;
+
+public class Order implements Serializable {
+
+ private static final long serialVersionUID = -3858669033991459168L;
+
+ private Long id;
+
+ private List<Item> items;
+
+ private Payment payment;
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public List<Item> getItems() {
+ return items;
+ }
+
+ public void setItems(List<Item> items) {
+ this.items = items;
+ }
+
+ public Payment getPayment() {
+ return payment;
+ }
+
+ public void setPayment(Payment payment) {
+ this.payment = payment;
+ }
+
+}
@@ -0,0 +1,29 @@
+package br.com.fixturefactory.model;
+
+import java.io.Serializable;
+
+public class Payment implements Serializable {
+
+ private static final long serialVersionUID = 8822301130570871333L;
+
+ private Long id;
+
+ private Order order;
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public Order getOrder() {
+ return order;
+ }
+
+ public void setOrder(Order order) {
+ this.order = order;
+ }
+
+}

0 comments on commit 97a9ed9

Please sign in to comment.