Skip to content

Commit d6db870

Browse files
committed
refactoring
1 parent 3c52574 commit d6db870

File tree

6 files changed

+206
-575
lines changed

6 files changed

+206
-575
lines changed

src/main/java/TestCaseInfo.java

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
import org.json.JSONArray;
2+
import org.json.JSONException;
3+
4+
public class TestCaseInfo {
5+
private String name;
6+
private String type;
7+
private boolean array;
8+
private TestCaseInfo enclosingVariable;
9+
10+
public TestCaseInfo(String name, String type, boolean array, TestCaseInfo enclosingVariable) {
11+
this.name = name;
12+
this.type = type;
13+
this.array = array;
14+
this.enclosingVariable = enclosingVariable;
15+
}
16+
17+
private String getValue(Object value) throws JSONException {
18+
if (isArray() && value instanceof JSONArray) {
19+
return getArray((JSONArray) value, type);
20+
} else {
21+
return getValue(value, type);
22+
}
23+
}
24+
25+
private String getValue(Object value, String type) {
26+
if (value == null) {
27+
return "null";
28+
}
29+
if (type.equals("string")) {
30+
/* make sure it fits on 1 line by removing new line chars */
31+
value = removeNewLines(value.toString());
32+
/* escape quotes */
33+
value = ((String) value).replaceAll("\\\"", "\\\\\"");
34+
return "\"" + value.toString() + "\"";
35+
36+
} else if (type.equals("number")) {
37+
return value.toString();
38+
39+
} else if (type.equals("boolean")) {
40+
if (value.toString().equals("true")) {
41+
return "1";
42+
} else {
43+
return "0";
44+
}
45+
} else if (type.equals("object")) {
46+
return "\"" + value.toString() + "\"";
47+
}
48+
return null;
49+
}
50+
51+
private static String removeNewLines(String html) {
52+
return html.replaceAll("[\\t\\n\\x0B\\f\\r]", "");
53+
}
54+
55+
private String getArray(JSONArray array, String type) throws JSONException {
56+
String result = "[";
57+
58+
for (int i = 0; i < array.length(); i++) {
59+
if (i != 0) {
60+
result += " ";
61+
}
62+
result += getValue(array.get(i), type);
63+
}
64+
return result + "]";
65+
}
66+
67+
String getDeclaration() {
68+
StringBuffer varDecl = new StringBuffer();
69+
70+
if (isArray()) {
71+
varDecl.append("\tvariable " + name + "[..]\n");
72+
varDecl.append("\t\tvar-kind array\n\t\tarray 1\n");
73+
varDecl.append("\t\tenclosing-var " + getEnclosingVariable().getName() + "\n");
74+
} else {
75+
varDecl.append("\tvariable " + name + "\n");
76+
varDecl.append("\t\tvar-kind field " + name + "\n");
77+
}
78+
varDecl.append("\t\tdec-type " + type + "\n");
79+
varDecl.append("\t\trep-type ");
80+
81+
if (type.equals("string")) {
82+
varDecl.append("java.lang.String");
83+
} else if (type.equals("boolean")) {
84+
varDecl.append("boolean");
85+
} else if (type.equals("undefined") || type.equals("function") || type.equals("object")
86+
|| type.equals("pointer")) {
87+
/*
88+
* for undefined, declare as hashcode. this doesn't really matter because it was
89+
* apparently never assigned a value. (at least we did not log a value).
90+
*/
91+
varDecl.append("hashcode");
92+
} else if (type.equals("number")) {
93+
/* number might be int or double. for now use double to be sure */
94+
varDecl.append("double");
95+
}
96+
97+
if (isArray()) {
98+
varDecl.append("[]");
99+
}
100+
varDecl.append("\n");
101+
102+
return varDecl.toString();
103+
}
104+
105+
public static TestCaseInfo parse(JSONArray var) throws JSONException {
106+
/* retrieve the three values from the array */
107+
String name = var.getString(0);
108+
String type = (String) var.getString(1);
109+
Object value;
110+
try {
111+
value = var.getJSONArray(2);
112+
} catch (JSONException e) {
113+
value = var.getString(2);
114+
/* make sure it fits on 1 line by removing new line chars */
115+
value = removeNewLines((String) value);
116+
/* escape quotes */
117+
value = ((String) value).replaceAll("\\\"", "\\\\\"");
118+
}
119+
120+
if (type.endsWith("_array")) {
121+
122+
type = type.replaceAll("_array", "");
123+
124+
TestCaseInfo enclosingVariable = new TestCaseInfo(name, "pointer", false, null);
125+
126+
return new TestCaseInfo(name, type, true, enclosingVariable);
127+
} else {
128+
return new TestCaseInfo(name, type, false, null);
129+
}
130+
}
131+
}

src/main/java/TestCodePropertyAnalyzer.java

Lines changed: 0 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -59,41 +59,6 @@ public static void main(String[] args) throws Exception {
5959
for (File file : files)
6060
processFile(file);
6161

62-
63-
64-
/*
65-
// Collect execution traces
66-
ArrayList traceList = null;
67-
HashMultimap<String, String> functionCallsMultiMap = HashMultimap.create();
68-
for (String jsFile: jsFileNames){
69-
System.out.println("Getting the traceList from " + jsFile);
70-
//System.out.println("return " + jsFile.replace(".js","") + "_getFuncionCallTrace();");
71-
//traceList = (ArrayList)((JavascriptExecutor) driver).executeScript("return " + jsFile.replace(".js","").replace("-", "_") + "_getFuncionCallTrace();");
72-
System.out.println("traceList: " + traceList);
73-
Map<String,String> traceMap;
74-
for (int i=0; i<traceList.size(); i++){
75-
traceMap = (Map<String,String>)(traceList.get(i));
76-
String testFunction = traceMap.get("testFunction");
77-
String calledFunctionName = traceMap.get("functionName");
78-
functionCallsMultiMap.put(testFunction, calledFunctionName);
79-
}
80-
}
81-
82-
int numUniqueFunCalls = 0;
83-
int maxUniqueFunCalls = 0;
84-
for (String testFunc : functionCallsMultiMap.keySet()) {
85-
Set<String> calledFunc = functionCallsMultiMap.get(testFunc);
86-
System.out.println(testFunc + ": " + calledFunc);
87-
if (calledFunc.size() > maxUniqueFunCalls)
88-
maxUniqueFunCalls = calledFunc.size();
89-
numUniqueFunCalls += calledFunc.size();
90-
}
91-
92-
System.out.println("numUniqueFunCalls: " + numUniqueFunCalls);
93-
if (functionCallsMultiMap.keySet().size()!=0)
94-
System.out.println("aveUniqueFunCalls: " + numUniqueFunCalls/functionCallsMultiMap.keySet().size());
95-
System.out.println("maxUniqueFunCalls: " + maxUniqueFunCalls);
96-
*/
9762
}
9863

9964
private static void processFile(File file) throws IOException, Exception {

src/main/java/core/JSAnalyzer.java

Lines changed: 50 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,45 @@ public void analyzeTestCodeProperties() throws Exception {
470470
astVisitor.setScopeName(scopeName);
471471
/* recurse through AST */
472472
ast.visit(astVisitor);
473+
474+
475+
476+
477+
/*
478+
// Collect execution traces
479+
ArrayList traceList = null;
480+
HashMultimap<String, String> functionCallsMultiMap = HashMultimap.create();
481+
for (String jsFile: jsFileNames){
482+
System.out.println("Getting the traceList from " + jsFile);
483+
//System.out.println("return " + jsFile.replace(".js","") + "_getFuncionCallTrace();");
484+
//traceList = (ArrayList)((JavascriptExecutor) driver).executeScript("return " + jsFile.replace(".js","").replace("-", "_") + "_getFuncionCallTrace();");
485+
System.out.println("traceList: " + traceList);
486+
Map<String,String> traceMap;
487+
for (int i=0; i<traceList.size(); i++){
488+
traceMap = (Map<String,String>)(traceList.get(i));
489+
String testFunction = traceMap.get("testFunction");
490+
String calledFunctionName = traceMap.get("functionName");
491+
functionCallsMultiMap.put(testFunction, calledFunctionName);
492+
}
493+
}
494+
495+
int numUniqueFunCalls = 0;
496+
int maxUniqueFunCalls = 0;
497+
for (String testFunc : functionCallsMultiMap.keySet()) {
498+
Set<String> calledFunc = functionCallsMultiMap.get(testFunc);
499+
System.out.println(testFunc + ": " + calledFunc);
500+
if (calledFunc.size() > maxUniqueFunCalls)
501+
maxUniqueFunCalls = calledFunc.size();
502+
numUniqueFunCalls += calledFunc.size();
503+
}
504+
505+
System.out.println("numUniqueFunCalls: " + numUniqueFunCalls);
506+
if (functionCallsMultiMap.keySet().size()!=0)
507+
System.out.println("aveUniqueFunCalls: " + numUniqueFunCalls/functionCallsMultiMap.keySet().size());
508+
System.out.println("maxUniqueFunCalls: " + maxUniqueFunCalls);
509+
*/
510+
511+
473512

474513
System.out.println("FunctionCalls :" + astVisitor.getFunctionCalls());
475514

@@ -481,57 +520,23 @@ public void analyzeTestCodeProperties() throws Exception {
481520
neverExecFunCallSites++;
482521
}
483522
}
484-
485-
coveredRegularFunc = astVisitor.getCoveredRegularFunc();
486-
missedRegularFunc = astVisitor.getMissedRegularFunc();
487-
coveredCallback = astVisitor.getCoveredCallback();
488-
missedCallback = astVisitor.getMissedCallback();
489-
coveredAsyncCallback = astVisitor.getCoveredAsyncCallback();
490-
missedAsyncCallback = astVisitor.getMissedAsyncCallback();
491-
coveredEventCallback = astVisitor.getCoveredAsyncCallback();
492-
missedEventCallback = astVisitor.getMissedEventCallback();
493-
coveredClosure = astVisitor.getCoveredClosure();
494-
missedClosure = astVisitor.getMissedClosure();
495-
496-
System.out.println("++++ coveredRegularFunc: " + astVisitor.getCoveredRegularFunc());
497-
System.out.println("++++ missedRegularFunc: " + astVisitor.getMissedRegularFunc());
498-
System.out.println("++++ coveredCallback: " + astVisitor.getCoveredCallback());
499-
System.out.println("++++ missedCallback: " + astVisitor.getMissedCallback());
500-
System.out.println("++++ coveredAsyncCallback: " + astVisitor.getCoveredAsyncCallback());
501-
System.out.println("++++ missedAsyncCallback: " + astVisitor.getMissedAsyncCallback());
502-
System.out.println("++++ coveredEventCallback: " + astVisitor.getCoveredAsyncCallback());
503-
System.out.println("++++ missedEventCallback: " + astVisitor.getMissedEventCallback());
504-
System.out.println("++++ coveredClosure: " + astVisitor.getCoveredClosure());
505-
System.out.println("++++ missedClosure: " + astVisitor.getMissedClosure());
506-
507-
System.out.println("++++ neverExecFunCallSites: " + neverExecFunCallSites);
508-
509-
510-
ArrayList<Integer> msimf = astVisitor.getMissedStatementInMissedFunction();
511-
//System.out.println("msimf: " + msimf);
512-
for (int i=0; i<msimf.size(); i++){
513-
if (msimf.get(i) >= 0)
514-
totalMissedStatementLinesInMissedFunctionCounter ++;
515-
}
516523

517-
totalMissedStatementLines = astVisitor.getMissedStatementLines().size();
518-
519-
System.out.println("@ Total missed statement lines in missed functioncounter = " + totalMissedStatementLinesInMissedFunctionCounter);
520-
System.out.println("@ Total number of missed statements = " + totalMissedStatementLines);
521-
if (totalMissedStatementLines!=0){
522-
float ratio = (float)totalMissedStatementLinesInMissedFunctionCounter/(float)totalMissedStatementLines;
523-
System.out.println("@ Percentage of missed statement in missed functions = " + ratio*100 + "%");
524-
}
525-
526-
524+
525+
NumTests = astVisitor.getTestCounter();
526+
NumAsyncTests = astVisitor.getAsynchTestCounter();
527+
NumAssertions = astVisitor.getAssertionCounter();
528+
//MaxFunCall = astVisitor.getMaxFunCall();
529+
//AveFunCall = astVisitor.getAveFunCall();
530+
//NumDOMFixture = astVisitor.getNumDOMFixture();
531+
NumTriggerTest = astVisitor.getTriggerCounetr();
532+
NumObjCreate = astVisitor.getNewExpressionCounter();
533+
527534
System.out.println("assertionCounter: " + astVisitor.getAssertionCounter());
528535
System.out.println("newExpressionCounter: " + astVisitor.getNewExpressionCounter());
529536
System.out.println("testCounter: " + astVisitor.getTestCounter());
530537
System.out.println("asynchTestCounter: " + astVisitor.getAsynchTestCounter());
531-
System.out.println("asynchTestCounter: " + astVisitor.getTestCounter());
532538
System.out.println("trieggerCounter: " + astVisitor.getTriggerCounetr());
533539

534-
535540
/* clean up */
536541
Context.exit();
537542
} catch (RhinoException re) {
@@ -541,6 +546,7 @@ public void analyzeTestCodeProperties() throws Exception {
541546
}
542547

543548
astVisitor.setVisitType("");
549+
astVisitor.resetTestCodeProperties();
544550
}
545551

546552
public int getNumTests() {

src/main/java/instrumentor/JSASTInstrumentor.java

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public class JSASTInstrumentor implements NodeVisitor{
3737
private int currentTestNumber = 0;
3838
private String currentTest = "";
3939
private int testCounter = 0;
40-
private int asynchTestCounter = 0;
40+
private int asyncTestCounter = 0;
4141
private int assertionCounter = 0;
4242
private int newExpressionCounter = 0;
4343
private int triggerCounetr = 0;
@@ -554,31 +554,28 @@ private void analyzeTestCodeFunctionCallNode(AstNode node) {
554554
if (node.getEnclosingFunction()!=null){
555555
enclosingFunction = getFunctionName(node.getEnclosingFunction());
556556
}
557-
System.out.println("enclosingFunction: " + enclosingFunction);
557+
//System.out.println("enclosingFunction: " + enclosingFunction);
558558

559559
if (node.shortName().equals("NewExpression"))
560560
return;
561561

562562
FunctionCall fcall = (FunctionCall) node;
563563
AstNode targetNode = fcall.getTarget(); // node evaluating to the function to call. E.g document.getElemenyById(x)
564-
System.out.println("targetNode.toSource(): " + targetNode.toSource());
565-
564+
//System.out.println("targetNode.toSource(): " + targetNode.toSource());
566565
String functionName = targetNode.toSource().substring(targetNode.toSource().lastIndexOf(".")+1);
567566

568567
if (testsFramework.equals("qunit")){
569568
if (targetNode.toSource().equals("QUnit.test") || targetNode.toSource().equals("test")){
570569
testCounter++;
571570
}
572-
if (targetNode.toSource().equals("QUnit.asyncTest()") || targetNode.toSource().equals("asyncTest()")){
571+
if (targetNode.toSource().equals("QUnit.asyncTest") || targetNode.toSource().equals("asyncTest")){
573572
testCounter++;
574-
asynchTestCounter++;
575-
setAsynchTestCounter(getAsynchTestCounter() + 1);
573+
asyncTestCounter++;
576574
}
577-
}
578-
575+
}
579576

580577
if (targetNode.toSource().equals("trigger") || targetNode.toSource().equals("triggerHandler"))
581-
setTriggerCounetr(getTriggerCounetr() + 1);
578+
triggerCounetr++;
582579

583580
String[] assertionSkipList = { "assert.expect", "expect", "assert.equal", "equal", "assert.notEqual", "notEqual", "assert.deepEqual", "deepEqual",
584581
"assert.notDeepEqual", "notDeepEqual", "assert.strictEqual", "strictEqual", "assert.notStrictEqual", "notStrictEqual", "QUnit.ok", "assert.ok", "ok", "assert.notOk", "notOk",
@@ -587,13 +584,17 @@ private void analyzeTestCodeFunctionCallNode(AstNode node) {
587584
String[] otherSkipList = { "QUnit.module", "module", "QUnit.test", "test", "QUnit.asyncTest", "asyncTest", "jQuery", "$" , "start", "stop"}; // start/stop for asynchronous control
588585

589586
if (ArrayUtils.contains( assertionSkipList, targetNode.toSource() ))
590-
setAssertionCounter(getAssertionCounter() + 1);
587+
assertionCounter++;
591588

592589
if (ArrayUtils.contains( assertionSkipList, targetNode.toSource() ) || ArrayUtils.contains( otherSkipList, targetNode.toSource() )) {
593-
System.out.println("Not counting the called function: " + targetNode.toSource());
590+
System.out.println("Not counting the called function: " + functionName);
594591
return;
595-
}else
592+
}else{
596593
System.out.println("Counting the called function: " + functionName);
594+
if (!functionCalls.contains(functionName))
595+
functionCalls.add(functionName);
596+
597+
}
597598

598599
}
599600

@@ -806,11 +807,11 @@ public void setTestCounter(int testCounter) {
806807
}
807808

808809
public int getAsynchTestCounter() {
809-
return asynchTestCounter;
810+
return asyncTestCounter;
810811
}
811812

812813
public void setAsynchTestCounter(int asynchTestCounter) {
813-
this.asynchTestCounter = asynchTestCounter;
814+
this.asyncTestCounter = asynchTestCounter;
814815
}
815816

816817
public int getTriggerCounetr() {
@@ -977,5 +978,14 @@ public void setTestFramework(String testsFramework) {
977978
}
978979

979980

981+
public void resetTestCodeProperties() {
982+
this.testCounter = 0;
983+
this.asyncTestCounter = 0;
984+
this.assertionCounter = 0;
985+
this.newExpressionCounter = 0;
986+
this.triggerCounetr = 0;
987+
}
988+
989+
980990
}
981991

0 commit comments

Comments
 (0)