1 package com.lexicalscope.fluentreflection.endtoend;
2
3 import static com.lexicalscope.fluentreflection.FluentReflection.*;
4 import static com.lexicalscope.fluentreflection.ReflectionMatchers.*;
5 import static org.hamcrest.MatcherAssert.assertThat;
6 import static org.hamcrest.Matchers.*;
7
8 import org.hamcrest.Matchers;
9 import org.junit.Rule;
10 import org.junit.Test;
11 import org.junit.rules.ExpectedException;
12
13 import com.lexicalscope.fluentreflection.FieldNotFoundException;
14 import com.lexicalscope.fluentreflection.FluentClass;
15 import com.lexicalscope.fluentreflection.FluentField;
16 import com.lexicalscope.fluentreflection.FluentObject;
17 import com.lexicalscope.fluentreflection.ReflectionRuntimeException;
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36 public class TestReflectedClassFields {
37 @Rule public ExpectedException exception = ExpectedException.none();
38
39 public static class Fields {
40 public String publicField;
41 String packageField;
42 protected String field2;
43 private String field3;
44 public static String staticField0;
45 public static final String staticFinalField0 = "value";
46 public final String finalField0 = "value";
47 }
48
49 @Test public void canFindFieldByName() throws SecurityException, NoSuchFieldException {
50 assertThat(
51 type(Fields.class).fields(hasName("publicField")),
52 contains(isReflectingOnField(Fields.class.getDeclaredField("publicField"))));
53 }
54
55 @Test public void canNotFindStaticFieldOfBoundObject() throws SecurityException, NoSuchFieldException {
56 assertThat(
57 object(new Fields()).fields(hasName("staticField0")),
58 Matchers.<FluentField>empty());
59 }
60
61 @Test public void canWriteField() throws SecurityException, NoSuchFieldException {
62 final FluentObject<Fields> object = object(new Fields());
63 final FluentField field = object.field(hasName("publicField"));
64
65 field.callRaw("value");
66 assertThat(
67 field.callRaw(),
68 equalTo((Object) "value"));
69 }
70
71 @Test public void fieldDeclaringTypeIsCorrect() throws SecurityException, NoSuchFieldException {
72 assertThat(
73 type(Fields.class).field(hasName("publicField")),
74 declaredBy(Fields.class));
75 }
76
77 @Test public void finalFieldsAreMarkedAsFinal() throws SecurityException, NoSuchFieldException {
78 assertThat(
79 type(Fields.class).field(hasName("finalField0")),
80 isFinal());
81 }
82
83 @Test public void propertyNameIsAvailable() throws SecurityException, NoSuchFieldException {
84 assertThat(
85 type(Fields.class).field(hasName("publicField")),
86 hasName("publicField").and(hasPropertyName("publicField")));
87 }
88
89 @Test public void fieldHasOneArgument() throws SecurityException, NoSuchFieldException {
90 assertThat(
91 type(Fields.class).field(hasName("publicField")),
92 hasArgumentCount(1));
93 }
94
95 @Test public void publicFieldToStringIsUseful() throws SecurityException, NoSuchFieldException {
96 assertThat(
97 type(Fields.class).field(hasName("publicField")),
98 hasToString("public java.lang.String publicField"));
99 }
100
101 @Test public void packageToStringIsUseful() throws SecurityException, NoSuchFieldException {
102 assertThat(
103 type(Fields.class).field(hasName("packageField")),
104 hasToString("java.lang.String packageField"));
105 }
106
107 @Test public void staticToStringIsUseful() throws SecurityException, NoSuchFieldException {
108 assertThat(
109 type(Fields.class).field(hasName("staticField0")),
110 hasToString("public static java.lang.String staticField0"));
111 }
112
113 @Test public void staticFinalToStringIsUseful() throws SecurityException, NoSuchFieldException {
114 assertThat(
115 type(Fields.class).field(hasName("staticFinalField0")),
116 hasToString("public static final java.lang.String staticFinalField0"));
117 }
118
119 @Test public void boundToStringIsUseful() throws SecurityException, NoSuchFieldException {
120 assertThat(
121 object(new Fields()).field(hasName("publicField")),
122 hasToString(startsWith("public java.lang.String publicField")));
123 }
124
125 @Test public void boundEqualsIsTrueForTheSameInstance() throws SecurityException, NoSuchFieldException {
126 final Fields instance = new Fields();
127 assertThat(
128 object(instance).field(hasName("publicField")),
129 equalTo(object(instance).field(hasName("publicField"))));
130 }
131
132 @Test public void hashCodeIsTheSameForTheSameBoundInstance() throws SecurityException, NoSuchFieldException {
133 final Fields instance = new Fields();
134 assertThat(
135 object(instance).field(hasName("publicField")).hashCode(),
136 equalTo(object(instance).field(hasName("publicField")).hashCode()));
137 }
138
139 @Test public void boundEqualsIsFalseForTheDifferentBoundInstances() throws SecurityException, NoSuchFieldException {
140 assertThat(
141 object(new Fields()).field(hasName("publicField")),
142 not(equalTo(object(new Fields()).field(hasName("publicField")))));
143 }
144
145 @Test public void equalsIsTrueWhenTheFieldsAreTheSameAsEachOther() throws SecurityException, NoSuchFieldException {
146 final FluentField field = object(new Fields()).field(hasName("publicField"));
147 assertThat(field, equalTo(field));
148 }
149
150 @Test public void equalsIsTrueWhenTheThatIsARandomOtherObject() throws SecurityException, NoSuchFieldException {
151 final FluentField field = object(new Fields()).field(hasName("publicField"));
152 assertThat(field, not(equalTo(new Object())));
153 }
154
155 @Test public void cannotReadFieldWithoutInstance() throws SecurityException, NoSuchFieldException {
156 final FluentClass<Fields> object = type(Fields.class);
157 final FluentField field = object.field(hasName("publicField"));
158
159 exception.expect(ReflectionRuntimeException.class);
160 exception.expectMessage("reading a field requires an instance argument");
161 field.callRaw();
162 }
163
164 @Test public void cannotCallFieldWithTooManyArguments() throws SecurityException, NoSuchFieldException {
165 final FluentClass<Fields> object = type(Fields.class);
166 final FluentField field = object.field(hasName("publicField"));
167
168 exception.expect(ReflectionRuntimeException.class);
169 exception.expectMessage("reading a field requires one argument, writing a field requires two arguments. Got 3 arguments");
170 field.callRaw(new Fields(), "value", "excess argument");
171 }
172
173 @Test public void missingFieldThrowsException() throws SecurityException, NoSuchFieldException {
174 exception.expect(FieldNotFoundException.class);
175 object(new Fields()).field(hasName("noSuchField"));
176 }
177 }