I am trying to make some JUnit tests for my code. But the problem is, I make use of the Java Models like ICompilationUnit, IPackageFragment, ITypes and etc. I did not get how to create some ICompilationUnit and then test. I searched google and stackoverflow for information but did not find something.
My question is, how can I make Junit test with classes of the jdt.core...can somebody give me may be some code examples.
Thanks
Here is a Method I coded:
private void updateLists() {
if(!getCompilationUnit().isEmpty()){
for(int i = 0; i < getCompilationUnit().size(); i++){
try {
Document doc = new Document(getCompilationUnit().get(i).getSource());
int totalNumberOfCode = doc.getNumberOfLines();
IType type = getCompilationUnit().get(i).findPrimaryType();
IType[] types = getCompilationUnit().get(i).getTypes();
updateListPrimaryType(type, totalNumberOfCode, types);
updateListIMethod(type);
updateListMember(type,types);
} catch (JavaModelException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
This snippet of code shows how to take some Java source (in variable javaSource) and get an ICompilationUnit from it by using the Java AST parser. You get these classes by using plugin org.eclipse.jdt.core as a dependency.
import org.eclipse.jdt.core.dom.ASTParser;
String javaSource = "some java source"'
// see org.eclipse.jdt.core.dom.AST for a complete
// list of supported levels.
ASTParser parser = ASTParser.newParser(AST.JLS2);
parser.setSource(javaSource.toCharArray());
CompilationUnit unit = (CompilationUnit) parser.createAST(null);
Related
I have been trying many of the examples provided and have yet to be successful. Here is the code I am currently trying, but getting an error in Eclipse on Paths.of (the of is underlined in red) that says: "rename in file".
String content;
try {
content = Files.readAllLines(Paths.of("C:", "Calcs.txt"));
} catch (IOException e1) {
e1.printStackTrace ();
}
System.out.println (content);
First it is not possible, if you get a list as return type, to assign this to a string. So you must write:
List<String> content;
Second regarding to the Java 8 documentation there is no method of available for this class. You can use the method get like this:
List<String> content = Files.readAllLines(Paths.get("C:", "Calcs.txt"));
Otherwise there exists a method of in the Path class since Java 11. Therefore you can write something like that:
List<String> content = Files.readAllLines(Path.of("C:", "Calcs.txt"));
You're probably looking for Paths.get:
String content;
try {
content = String.join("\n", Files.readAllLines(Paths.get("/home/hassan", "Foo.java")));
} catch (IOException e1) {
e1.printStackTrace ();
}
I have built a program, which takes in a provided ".class" file and parses it using the BCEL, I've learnt how to calculate the LCOM4 value now. Now I would like to know how to calculate the CBO(Coupling between object) value of the class file. I've scoured the whole web, trying to find a proper tutorial about it, but I've been unable so far (I've read the whole javadoc regarding the BCEL as well and there was a similar question on stackoverflow but it has been removed). So I would like some help with this issue, as in some detailed tutorials or code snippets that would help me understand on how to do it.
OK, here you must compute the CBO of the classes within a whole set of classes. The set can be the content of a directory, of a jar file, or all the classes in a classpath.
I would fill a Map<String,Set<String>> with the class name as the key, and the classes it refers to:
private void addClassReferees(File file, Map<String, Set<String>> refMap)
throws IOException {
try (InputStream in = new FileInputStream(file)) {
ClassParser parser = new ClassParser(in, file.getName());
JavaClass clazz = parser.parse();
String className = clazz.getClassName();
Set<String> referees = new HashSet<>();
ConstantPoolGen cp = new ConstantPoolGen(clazz.getConstantPool());
for (Method method: clazz.getMethods()) {
Code code = method.getCode();
InstructionList instrs = new InstructionList(code.getCode());
for (InstructionHandle ih: instrs) {
Instruction instr = ih.getInstruction();
if (instr instanceof FieldOrMethod) {
FieldOrMethod ref = (FieldInstruction)instr;
String cn = ref.getClassName(cp);
if (!cn.equals(className)) {
referees.add(cn);
}
}
}
}
refMap.put(className, referees);
}
}
When you've added all the classes in the map, you need to filter the referees of each class to limit them to the set of classes considered, and add the backward links:
Set<String> classes = new TreeSet<>(refMap.keySet());
for (String className: classes) {
Set<String> others = refMap.get(className);
others.retainAll(classes);
for (String other: others) {
refMap.get(other).add(className);
}
}
I'm working on setting up an automated processing system for a (ever growing) unstructured collection of excel documents. The collection consists of both old-school .xls files and new .xlsx files. In my Java-based solution I am already making use of the Apache POI toolkit to analyse the documents.
One challenges that I have not been able to tackle yet, is how to identify links between documents so as to chart dependencies. I have not yet been able to figure out how to conveniently extract a list of external references. For .xlsx files I have a workaround in place that unzips the file, and opens the xml file holding the references. This works but is inefficient for large document collections, and also does not provide a solution for .xls files.
I prefer to have a solution that is not dependent on Microsoft Office or associated libraries as the solution needs to run on a Linux environment.
Is POI capable of doing this somehow? If not, what would be suggested libraries/tools/area's that I could further investigate?
Ultimately I worked my way through the POI source code and used reflection to get a list of referenced external workbooks. The following code was tested to work on POI version 3.11 beta.
Note for people looking to use this method in there code: Because it deals with non-public methods and classes, it is subject to change and may break in the future.
private LinkedList<String> getWorkbookReferences(HSSFWorkbook wb) {
LinkedList<String> references = new LinkedList<>();
try {
// 1. Get InternalWorkbook
Field internalWorkbookField = HSSFWorkbook.class.getDeclaredField("workbook");
internalWorkbookField.setAccessible(true);
InternalWorkbook internalWorkbook = (InternalWorkbook) internalWorkbookField.get(wb);
// 2. Get LinkTable (hidden class)
Method getLinkTableMethod;
getLinkTableMethod = InternalWorkbook.class.getDeclaredMethod("getOrCreateLinkTable", null);
getLinkTableMethod.setAccessible(true);
Object linkTable = getLinkTableMethod.invoke(internalWorkbook, null);
// 3. Get external books method
Method externalBooksMethod = linkTable.getClass().getDeclaredMethod("getExternalBookAndSheetName", int.class);
externalBooksMethod.setAccessible(true);
// 4. Loop over all possible workbooks
int i = 0;
String[] names;
try {
while( true) {
names = (String[]) externalBooksMethod.invoke(linkTable, i++) ; if (names != null ) {
references.add(names[0]);
}
}
}
catch ( java.lang.reflect.InvocationTargetException e) {
if ( !(e.getCause() instanceof java.lang.IndexOutOfBoundsException) ) {
throw e;
}
}
} catch (NoSuchFieldException | NoSuchMethodException | SecurityException | InvocationTargetException | IllegalAccessException e) {
e.printStackTrace();
}
return references;
}
I want to be able to mock the File object in java using Mockery. I seems like we may not be able to create an interface for the File in java. Is this possible?
EDIT:
I need to test the indexDoc function in Indexer Class.
#Test
public void testindexDocs()
{
final File f = mockFile.mock(File.class);
File file = new File("test");
mockFile.setImposteriser(ClassImposteriser.INSTANCE);
final String[] files = {
"C:\\test\\",
"C:\\test\\test1.html",
"C:\\test\\test2",
"C:\\test\\test3.html"};
mockFile.checking(new Expectations(){
{
one(f).list();will(returnValue(files));
}
});
//TODO test if list() how many time i have called
//Document doc = HTMLDocument.Document(file); in function indexDocs
}
Index Docs function in Indexer class
private static void indexDocs(File file) throws Exception{
//Check for file to be a directory or file to be indexed look for html files and add to document
if(file.isDirectory()){
String[] files = file.list();
Arrays.sort(files);
for (int i = 0; i < files.length; i++) // recursively index them
indexDocs(new File(file, files[i]));
} else if(file.getPath().endsWith(".html") || file.getPath().endsWith("htm")){
// Get the document from HTMLDocument class which takes care of stripping of HTML tag, get the path
// of HTML file and title of HTML document.
Document doc = HTMLDocument.Document(file);
// TODO Get the book of HTML, it can be a part of HTML document class.
writer.addDocument(doc);
}
}
Don't mock the file system. We tried to do this in the early days and it diverted us from using tests to guide the design.
From a quick look at your code, there are two things going on, one is file navigation, the other is html stripping. Perhaps one option would be to introduce a html stripping object (passed in as a collaborator) and mock that, then write tests against examples in a real file system.
Jmock can mock concrete classes. Just do
Mockery context = new Mockery();
context.setImposteriser(ClassImposteriser.INSTANCE);
The problems your having are the exact reason, one should use abstractions rather than concrete classes.
In my code, all of the scripts are contained in .js files. Whenever one of the scripts contains an error, I get this:
javax.script.ScriptException: sun.org.mozilla.javascript.internal.EcmaError: ReferenceError: "nonexistant" is not defined. (<Unknown source>#5) in <Unknown source> at line number 5
What bugs me is the <Unknown Source>. Multiple files are in one ScriptContext, and it can be hard to track down an error. It also looks horrible.
Is there a way to replace <Unknown Source> with the actual file name? None of the methods I see support passing a File object, so I'm really confused here.
Use the ScriptEngine.FILENAME constant:
scriptEngine.put(ScriptEngine.FILENAME, scriptFile.toString());
The question hasn't been specifically asked yet, but I thought I'd offer this to anyone who stumbles upon this topic in the future: this will change when Java 8 is released and we move from Rhino to Nashorn as the underlying JavaScript engine. Under Nashorn, the file name is applied to the ScriptContext, rather than to the ScriptEngine itself:
ScriptContext context = new SimpleScriptContext();
context.setAttribute(ScriptEngine.FILENAME, "test.js", ScriptContext.ENGINE_SCOPE);
try
{
engine.eval(script, context);
}
catch (ScriptException e)
{
/* e.getFileName() will return "test.js" */
}
If you attempt to apply the file name using ScriptEngine.put(), as you do under Rhino, nothing will happen and your exceptions will return "<eval>" as the file name.
I would imagine that a few people will run into this issue in the coming months, so thought I'd offer it. This does not appear to be documented anywhere. I had to dig into the Nashorn source code to figure it out.
The Java 8 (Nashorn) way of setting the filename for the script engine through the ScriptContext figured out by mattj65816, works for the Rhino engine as well. So, I'd recommend using only
context.setAttribute(ScriptEngine.FILENAME, "test.js", ScriptContext.ENGINE_SCOPE);
since this piece of code works for both common JavaScript engines. You don't event need to create you own context, but only set the attribute to the engine's default context:
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("JavaScript");
if (engine != null) {
ScriptContext ctx = engine.getContext();
ctx.setAttribute(ScriptEngine.FILENAME, "test.js", ScriptContext.ENGINE_SCOPE);
...
}
perfect!
ScriptEngine engine = new ScriptEngineManager().getEngineByExtension("js");
// javax.script.filename
engine.put(ScriptEngine.FILENAME, "test1.js");
try {
engine.eval("function throwError1(){throw new Error('test, haha')}");
} catch (ScriptException e) {
}
engine.put(ScriptEngine.FILENAME, "test2.js");
try {
engine.eval("function throwError2(){throw new Error('test2, haha')}");
} catch (ScriptException e) {
}
try {
engine.eval("throwError1()");
} catch (ScriptException e) {
System.out.println(e.getMessage());
}
try {
engine.eval("throwError2()");
} catch (ScriptException e) {
System.out.println(e.getMessage());
}
output :
Error: test, haha in test1.js at line number 1
Error: test2, haha in test2.js at line number 1