dbremner / testability-explorer

Automatically exported from code.google.com/p/testability-explorer
Apache License 2.0
0 stars 0 forks source link

Should Java classes be whitelisted by default ? #13

Open GoogleCodeExporter opened 8 years ago

GoogleCodeExporter commented 8 years ago
What steps will reproduce the problem?
1. Have some method which creates a new Date object inline and does some
work with it
2. Run TE on said class / method

What is the expected output? What do you see instead?

The report shows that the method is super testable, because, all java.*
classes are whitelisted. I am not sure this is the correct approach,
because creating a bunch of date objects inline is a sure fire way to make
code untestable. But the report would say otherwise. Maybe the solution is
that instead of just whitelisting, atleast assign a token cost so that the
issue is atleast raised ?

I am not sure what the best way forward is, but its definitely not
whitelisting every java class.

Original issue reported on code.google.com by shyamseshadri on 27 Mar 2009 at 8:09

GoogleCodeExporter commented 8 years ago
I don't know about a token cost either.  What happens when we completely don't 
whitelist java.*?  I think you 
definitely need a cost for using the new operator, so maybe that's your token 
cost - but you should be 
inheriting any inseparable complexity, just like you should if you call a 
static method (which new sort of is, in a 
sense)

Original comment by christia...@gmail.com on 27 Mar 2009 at 8:27

GoogleCodeExporter commented 8 years ago
If we don't whitelist java.*, then for example, when you say inside a method :

return new Date(lockedUntil).toString();

You get assigned a complexity (or was it global) cost of around 3000.

Date is nasty, apparently. But the minute you whitelist it,
the score drops to 0.

Obviously, both of these are not acceptable.
Because in the case where I was getting a 3000 cost, it actually was still 
testable
because I believe the lockedUntil was injected (or could be set) in the class 
it was
used.

Original comment by shyamseshadri on 27 Mar 2009 at 9:54

GoogleCodeExporter commented 8 years ago
3000?  Wow! How did it end up with 3000?  I think that would be a good thing to 
know.

Original comment by christia...@gmail.com on 27 Mar 2009 at 11:46

GoogleCodeExporter commented 8 years ago
Here's the bytecode and source from my system
(/System/Library/Frameworks/JavaVM.framework/Versions/1.6.0/Home/lib/dt.jar)

I'd say that on the one hand, using crappy JRE code is a choice, you could use 
better
libraries. But we're kind of stuck with the useless java.util.Date. Even if 
you're
forced to use it, calling toString is not a good practice, you should be using a
DateFormatter. Could you plug that into your test and see what score you get?
{{{
public String toString() {
    // "EEE MMM dd HH:mm:ss zzz yyyy";
    BaseCalendar.Date date = normalize();
    StringBuilder sb = new StringBuilder(28);
    int index = date.getDayOfWeek();
    if (index == gcal.SUNDAY) {
        index = 8;
    }
    convertToAbbr(sb, wtb[index]).append(' ');            // EEE
    convertToAbbr(sb, wtb[date.getMonth() - 1 + 2 + 7]).append(' ');  // MMM
    CalendarUtils.sprintf0d(sb, date.getDayOfMonth(), 2).append(' '); // dd

    CalendarUtils.sprintf0d(sb, date.getHours(), 2).append(':');   // HH
    CalendarUtils.sprintf0d(sb, date.getMinutes(), 2).append(':'); // mm
    CalendarUtils.sprintf0d(sb, date.getSeconds(), 2).append(' '); // ss
    TimeZone zi = date.getZone();
    if (zi != null) {
        sb.append(zi.getDisplayName(date.isDaylightTime(), zi.SHORT, Locale.US)); // zzz
    } else {
        sb.append("GMT");
    }
    sb.append(' ').append(date.getYear());  // yyyy
    return sb.toString();
    }

public java.lang.String toString();
  Code:
   0:   aload_0
   1:   invokespecial   #37; //Method normalize:()Lsun/util/calendar/BaseCalendar$Date;
   4:   astore_1
   5:   new #56; //class java/lang/StringBuilder
   8:   dup
   9:   bipush  28
   11:  invokespecial   #57; //Method java/lang/StringBuilder."<init>":(I)V
   14:  astore_2
   15:  aload_1
   16:  invokevirtual   #46; //Method sun/util/calendar/BaseCalendar$Date.getDayOfWeek:()I
   19:  istore_3
   20:  iload_3
   21:  getstatic   #29; //Field gcal:Lsun/util/calendar/BaseCalendar;
   24:  pop
   25:  iconst_1
   26:  if_icmpne   32
   29:  bipush  8
   31:  istore_3
   32:  aload_2
   33:  getstatic   #25; //Field wtb:[Ljava/lang/String;
   36:  iload_3
   37:  aaload
   38:  invokestatic    #58; //Method
convertToAbbr:(Ljava/lang/StringBuilder;Ljava/lang/String;)Ljava/lang/StringBuil
der;
   41:  bipush  32
   43:  invokevirtual   #59; //Method
java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
   46:  pop
   47:  aload_2
   48:  getstatic   #25; //Field wtb:[Ljava/lang/String;
   51:  aload_1
   52:  invokevirtual   #41; //Method sun/util/calendar/BaseCalendar$Date.getMonth:()I
   55:  iconst_1
   56:  isub
   57:  iconst_2
   58:  iadd
   59:  bipush  7
   61:  iadd
   62:  aaload
   63:  invokestatic    #58; //Method
convertToAbbr:(Ljava/lang/StringBuilder;Ljava/lang/String;)Ljava/lang/StringBuil
der;
   66:  bipush  32
   68:  invokevirtual   #59; //Method
java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
   71:  pop
   72:  aload_2
   73:  aload_1
   74:  invokevirtual   #44; //Method sun/util/calendar/BaseCalendar$Date.getDayOfMonth:()I
   77:  iconst_2
   78:  invokestatic    #60; //Method
sun/util/calendar/CalendarUtils.sprintf0d:(Ljava/lang/StringBuilder;II)Ljava/lan
g/StringBuilder;
   81:  bipush  32
   83:  invokevirtual   #59; //Method
java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
   86:  pop
   87:  aload_2
   88:  aload_1
   89:  invokevirtual   #47; //Method sun/util/calendar/BaseCalendar$Date.getHours:()I
   92:  iconst_2
   93:  invokestatic    #60; //Method
sun/util/calendar/CalendarUtils.sprintf0d:(Ljava/lang/StringBuilder;II)Ljava/lan
g/StringBuilder;
   96:  bipush  58
   98:  invokevirtual   #59; //Method
java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
   101: pop
   102: aload_2
   103: aload_1
   104: invokevirtual   #49; //Method sun/util/calendar/BaseCalendar$Date.getMinutes:()I
   107: iconst_2
   108: invokestatic    #60; //Method
sun/util/calendar/CalendarUtils.sprintf0d:(Ljava/lang/StringBuilder;II)Ljava/lan
g/StringBuilder;
   111: bipush  58
   113: invokevirtual   #59; //Method
java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
   116: pop
   117: aload_2
   118: aload_1
   119: invokevirtual   #51; //Method sun/util/calendar/BaseCalendar$Date.getSeconds:()I
   122: iconst_2
   123: invokestatic    #60; //Method
sun/util/calendar/CalendarUtils.sprintf0d:(Ljava/lang/StringBuilder;II)Ljava/lan
g/StringBuilder;
   126: bipush  32
   128: invokevirtual   #59; //Method
java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
   131: pop
   132: aload_1
   133: invokevirtual   #61; //Method
sun/util/calendar/BaseCalendar$Date.getZone:()Ljava/util/TimeZone;
   136: astore  4
   138: aload   4
   140: ifnull  167
   143: aload_2
   144: aload   4
   146: aload_1
   147: invokevirtual   #62; //Method
sun/util/calendar/BaseCalendar$Date.isDaylightTime:()Z
   150: aload   4
   152: pop
   153: iconst_0
   154: getstatic   #63; //Field java/util/Locale.US:Ljava/util/Locale;
   157: invokevirtual   #64; //Method
java/util/TimeZone.getDisplayName:(ZILjava/util/Locale;)Ljava/lang/String;
   160: invokevirtual   #65; //Method
java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   163: pop
   164: goto    174
   167: aload_2
   168: ldc #66; //String GMT
   170: invokevirtual   #65; //Method
java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   173: pop
   174: aload_2
   175: bipush  32
   177: invokevirtual   #59; //Method
java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
   180: aload_1
   181: invokevirtual   #38; //Method sun/util/calendar/BaseCalendar$Date.getYear:()I
   184: invokevirtual   #67; //Method
java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
   187: pop
   188: aload_2
   189: invokevirtual   #68; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
   192: areturn
}}}

Original comment by aeagle22206 on 30 Mar 2009 at 2:59

GoogleCodeExporter commented 8 years ago
I have similar issues with creating an java.net.URL call:

<cost cyclomatic="3587" global="238" line="235" lod="0"
method="java.net.URL(java.lang.String)" overall="5967" reason="cost from calling
non-overridable method" />

Is this expected?  I'm just doing "new URL(urlString);" in the method...

PS: This is with the latest 1.3 build

Original comment by pedro....@gmail.com on 29 Apr 2009 at 5:49