11package com .futurist_labs .android .base_library .utils .test ;
22
3+ import com .futurist_labs .android .base_library .utils .Texter ;
4+
5+ import org .json .JSONArray ;
6+ import org .json .JSONException ;
7+ import org .json .JSONObject ;
8+
39import java .lang .annotation .Retention ;
410import java .lang .annotation .RetentionPolicy ;
511import java .lang .reflect .Field ;
612import java .util .ArrayList ;
713import java .util .Arrays ;
14+ import java .util .HashSet ;
815import java .util .List ;
16+ import java .util .Set ;
917
1018/**
1119 * Created by Galeen on 2019-08-13.
1220 * Helper class to test an object for NULL/Empty fields.
1321 * This way you can easily test server response for mandatory fields that are null or if a field
1422 * is removed from the server response.
15- *
16- * Todo check for extra fields added form the server
23+ * <p>
24+ * Todo check for extra fields added form the server, check transient fields
25+ * https://stackoverflow.com/questions/19551882/jsr-303-compatible-bean-validator-for-android
1726 */
18- public class CoreAnnotations {
27+ public class Tester {
1928
2029 /**
2130 * Fields with this annotation must be checked
2231 */
2332 @ Retention (RetentionPolicy .RUNTIME )
2433 public @interface MandatoryForTests {
2534 }
35+
2636 /**
2737 * Fields with this annotation must not be checked
2838 */
2939 @ Retention (RetentionPolicy .RUNTIME )
3040 public @interface ExcludeFromTests {
3141 }
42+
3243 /**
3344 * Fields with this annotation will be checked if are primitive type and if is default value
3445 */
3546 @ Retention (RetentionPolicy .RUNTIME )
3647 public @interface CheckDefaultPrimitiveInTests {
3748 }
49+
3850 /**
3951 * String Fields with this annotation will be checked for empty string also String.length == 0
4052 */
@@ -43,26 +55,20 @@ public class CoreAnnotations {
4355 }
4456
4557 /**
46- *
47- * @param t Object to test
58+ * @param t Object to test
4859 * @param fieldsWithoutAnnotationAreMandatory if true any field that has no annotation @ExcludeFromTests
4960 * will be treated as with @MandatoryForTests, else only fields that has
50- * @MandatoryForTests annotation will be checked
5161 * @return Null if all is good , else will be a string where each line represents the field and msg if is NULL , 0 or Empty
62+ * @MandatoryForTests annotation will be checked
5263 */
5364 public static <T > String getNullFields (T t , boolean fieldsWithoutAnnotationAreMandatory ) {
54- List <Field > fields = new ArrayList <>();
55- Class clazz = t .getClass ();
56- while (clazz != null && clazz != Object .class ) {
57- fields .addAll (Arrays .asList (clazz .getDeclaredFields ()));
58- clazz = clazz .getSuperclass ();
59- }
65+ List <Field > fields = getAllFields (t );
6066 int size = fields .size ();
6167 StringBuilder sb = new StringBuilder ();
6268 for (int i = 0 ; i < size ; i ++) {
6369 Field field = fields .get (i );
6470 if (!field .isAnnotationPresent (ExcludeFromTests .class ) &&
65- (fieldsWithoutAnnotationAreMandatory || field .isAnnotationPresent (MandatoryForTests .class ))) {
71+ (fieldsWithoutAnnotationAreMandatory || field .isAnnotationPresent (MandatoryForTests .class ))) {
6672 field .setAccessible (true );
6773 try {
6874 if (field .get (t ) == null ) {
@@ -87,6 +93,38 @@ public static <T> String getNullFields(T t, boolean fieldsWithoutAnnotationAreMa
8793 return sb .length () > 0 ? sb .toString () : null ;
8894 }
8995
96+ private static <T > List <Field > getAllFields (T t ) {
97+ List <Field > fields = new ArrayList <>();
98+ Class clazz = t .getClass ();
99+ while (clazz != null && clazz != Object .class ) {
100+ fields .addAll (Arrays .asList (clazz .getDeclaredFields ()));
101+ clazz = clazz .getSuperclass ();
102+ }
103+ return fields ;
104+ }
105+
106+ public static <T > Set <String > getExtraFields (T t , String jsonObjectString ,
107+ boolean fieldsWithoutAnnotationAreMandatory ) throws JSONException {
108+ if (t == null || Texter .isEmpty (jsonObjectString )) {
109+ return null ;
110+ }
111+ Set <String > errors = null ;
112+ JSONObject jsonObject = new JSONObject (jsonObjectString );
113+ JSONArray names = jsonObject .names ();
114+ int size = names == null ? 0 : names .length ();
115+ if (size > 0 ) {
116+ List <Field > fields = getAllFields (t );
117+ for (int i = 0 ; i < size ; i ++) {
118+ String name = names .getString (i );
119+ // TODO: 8/20/2019 check if name is field
120+ }
121+ }else {
122+ errors = new HashSet <>();
123+ errors .add ("Empty json" );
124+ }
125+ return errors ;
126+ }
127+
90128 private static <T > void checkDefaultPrimitive (final T t , final StringBuilder sb , final Field field ) throws IllegalAccessException {
91129 Object o = field .get (t );
92130 // any number type is fine.
0 commit comments