package com.google.jstestdriver.idea.assertFramework.qunit;
import com.google.jstestdriver.idea.assertFramework.AbstractTestFileStructureBuilder;
import com.google.jstestdriver.idea.util.CastUtils;
import com.google.jstestdriver.idea.util.JsPsiUtils;
import com.google.jstestdriver.idea.util.ObjectUtils;
import com.intellij.lang.javascript.psi.*;
import org.jetbrains.annotations.NotNull;
import java.util.List;
public class QUnitFileStructureBuilder extends AbstractTestFileStructureBuilder {
private static QUnitFileStructureBuilder ourInstance = new QUnitFileStructureBuilder();
@NotNull
@Override
public QUnitFileStructure buildTestFileStructure(@NotNull JSFile jsFile) {
return new Builder(jsFile).build();
}
private static class Builder {
private final QUnitFileStructure myFileStructure;
@NotNull
private AbstractQUnitModuleStructure myCurrentModuleStructure;
private Builder(JSFile jsFile) {
myFileStructure = new QUnitFileStructure(jsFile);
myCurrentModuleStructure = myFileStructure.getDefaultModuleStructure();
}
public QUnitFileStructure build() {
List<JSElement> jsElements = JsPsiUtils.listJsElementsInExecutionOrder(myFileStructure.getJsFile());
for (JSElement jsElement : jsElements) {
update(jsElement);
}
return myFileStructure;
}
private void update(JSElement jsElement) {
JSExpressionStatement expressionStatement = CastUtils.tryCast(jsElement, JSExpressionStatement.class);
if (expressionStatement != null) {
JSCallExpression callExpression = CastUtils.tryCast(expressionStatement.getExpression(), JSCallExpression.class);
if (callExpression != null) {
updateJsCallExpression(callExpression);
}
}
}
private void updateJsCallExpression(@NotNull JSCallExpression callExpression) {
JSReferenceExpression methodExpression = CastUtils.tryCast(callExpression.getMethodExpression(), JSReferenceExpression.class);
JSArgumentList argumentList = callExpression.getArgumentList();
if (methodExpression != null && argumentList != null) {
String methodName = methodExpression.getReferencedName();
JSExpression[] arguments = ObjectUtils.notNull(argumentList.getArguments(), JSExpression.EMPTY_ARRAY);
if (arguments.length >= 1) {
String name = JsPsiUtils.extractStringValue(arguments[0]);
if (name != null) {
if ("module".equals(methodName)) {
boolean ok = arguments.length == 1;
JSObjectLiteralExpression lifecycleObjectLiteral = null;
if (arguments.length == 2) {
lifecycleObjectLiteral = JsPsiUtils.extractObjectLiteralExpression(arguments[1]);
if (lifecycleObjectLiteral != null) {
ok = true;
}
}
if (ok) {
QUnitModuleStructure moduleStructure = new QUnitModuleStructure(myFileStructure, name, callExpression, lifecycleObjectLiteral);
myFileStructure.addModuleStructure(moduleStructure);
myCurrentModuleStructure = moduleStructure;
}
} else if ("test".equals(methodName) && arguments.length == 2) {
JSFunctionExpression body = JsPsiUtils.extractFunctionExpression(arguments[1]);
if (body != null) {
QUnitTestMethodStructure testMethodStructure = new QUnitTestMethodStructure(myCurrentModuleStructure, name, callExpression, body);
myCurrentModuleStructure.addTestMethodStructure(testMethodStructure);
}
}
}
}
}
}
}
public static QUnitFileStructureBuilder getInstance() {
return ourInstance;
}
}