Skip to content

Commit

Permalink
Merge pull request #71 from devuxd/tests
Browse files Browse the repository at this point in the history
add tests for getSurroundingNodes
  • Loading branch information
SaharMehrpour authored May 30, 2024
2 parents 57d0f1f + 41b4887 commit 474611b
Show file tree
Hide file tree
Showing 3 changed files with 276 additions and 4 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
},
"devDependencies": {
"gh-pages": "3.1.0",
"jasmine": "^5.1.0",
"react-app-rewired": "2.1.8",
"react-scripts": "4.0.3"
},
Expand Down
8 changes: 4 additions & 4 deletions src/core/ruleExecutor.js
Original file line number Diff line number Diff line change
Expand Up @@ -683,15 +683,15 @@ function isClassOrField(node) {
}

/**
* remove function bodies
* remove function or constructor bodies
* @param node {Node}
*/
const removeFunctionBodies = (node) => {
export const removeFunctionBodies = (node) => {
if (!node || node.nodeType !== Node.ELEMENT_NODE) {
return;
}

if (node.tagName.toLowerCase() === "function") {
if (node.tagName.toLowerCase() === "function" || node.tagName.toLowerCase() === "constructor") {
for (let i = 0; i < node.childNodes.length; i++) {
const child = node.childNodes[i];
if (child.tagName && child.tagName.toLowerCase() === "block") {
Expand All @@ -711,7 +711,7 @@ const removeFunctionBodies = (node) => {
* remove bodies of sibling functions
* @param node {Node}
*/
const removeSiblingFunctionBodies = (node) => {
export const removeSiblingFunctionBodies = (node) => {
if (!node || node.nodeType !== Node.ELEMENT_NODE) {
return;
}
Expand Down
271 changes: 271 additions & 0 deletions src/core/ruleExecutor.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,271 @@
import {removeSiblingFunctionBodies, removeFunctionBodies} from "./ruleExecutor";

describe("removeFunctionBodies", () => {

/*
public class myClass {
@Id
public long ID;
public myClass() {
// constructor body
this.ID = 0;
}
public void myFunc(int param) {
// myFunc body
}
@annot
private String anotherFunc(String param) {
// anotherFunc body
}
}
*/
const xmlString =
`<unit xmlns="http://www.srcML.org/srcML/src" revision="0.9.5" language="Java"><class><specifier>public</specifier> class <name>myClass</name> <block>{
<decl_stmt><decl><annotation>@<name>Id</name></annotation>
<specifier>public</specifier> <type><name>long</name></type> <name>ID</name></decl>;</decl_stmt>
<constructor><specifier>public</specifier> <name>myClass</name><parameter_list>()</parameter_list> <block>{
<comment type="line">// constructor body</comment>
<expr_stmt><expr><name><name>this</name><operator>.</operator><name>ID</name></name> <operator>=</operator> <literal type="number">0</literal></expr>;</expr_stmt>
}</block></constructor>
<function><specifier>public</specifier> <type><name>void</name></type> <name>myFunc</name><parameter_list>(<parameter><decl><type><name>int</name></type> <name>param</name></decl></parameter>)</parameter_list> <block>{
<comment type="line">// myFunc body</comment>
}</block></function>
<function><annotation>@<name>annot</name></annotation>
<specifier>private</specifier> <type><name>String</name></type> <name>anotherFunc</name><parameter_list>(<parameter><decl><type><name>String</name></type> <name>param</name></decl></parameter>)</parameter_list> <block>{
<comment type="line">// anotherFunc body</comment>
}</block></function>
}</block></class>
</unit>`;

/*
public class myClass {
@Id
public long ID;
public myClass() {
// constructor body
this.ID = 0;
}
public void myFunc(int param)
@annot
private String anotherFunc(String param) {
// anotherFunc body
}
}
*/
const removedFirstFuncBody =
`<unit xmlns="http://www.srcML.org/srcML/src" revision="0.9.5" language="Java"><class><specifier>public</specifier> class <name>myClass</name> <block>{
<decl_stmt><decl><annotation>@<name>Id</name></annotation>
<specifier>public</specifier> <type><name>long</name></type> <name>ID</name></decl>;</decl_stmt>
<constructor><specifier>public</specifier> <name>myClass</name><parameter_list>()</parameter_list> <block>{
<comment type="line">// constructor body</comment>
<expr_stmt><expr><name><name>this</name><operator>.</operator><name>ID</name></name> <operator>=</operator> <literal type="number">0</literal></expr>;</expr_stmt>
}</block></constructor>
<function><specifier>public</specifier> <type><name>void</name></type> <name>myFunc</name><parameter_list>(<parameter><decl><type><name>int</name></type> <name>param</name></decl></parameter>)</parameter_list> </function>
<function><annotation>@<name>annot</name></annotation>
<specifier>private</specifier> <type><name>String</name></type> <name>anotherFunc</name><parameter_list>(<parameter><decl><type><name>String</name></type> <name>param</name></decl></parameter>)</parameter_list> <block>{
<comment type="line">// anotherFunc body</comment>
}</block></function>
}</block></class>
</unit>`;

/*
public class myClass {
@Id
public long ID;
public myClass()
public void myFunc(int param) {
// myFunc body
}
@annot
private String anotherFunc(String param) {
// anotherFunc body
}
}
*/
const removedConstrBody =
`<unit xmlns="http://www.srcML.org/srcML/src" revision="0.9.5" language="Java"><class><specifier>public</specifier> class <name>myClass</name> <block>{
<decl_stmt><decl><annotation>@<name>Id</name></annotation>
<specifier>public</specifier> <type><name>long</name></type> <name>ID</name></decl>;</decl_stmt>
<constructor><specifier>public</specifier> <name>myClass</name><parameter_list>()</parameter_list> </constructor>
<function><specifier>public</specifier> <type><name>void</name></type> <name>myFunc</name><parameter_list>(<parameter><decl><type><name>int</name></type> <name>param</name></decl></parameter>)</parameter_list> <block>{
<comment type="line">// myFunc body</comment>
}</block></function>
<function><annotation>@<name>annot</name></annotation>
<specifier>private</specifier> <type><name>String</name></type> <name>anotherFunc</name><parameter_list>(<parameter><decl><type><name>String</name></type> <name>param</name></decl></parameter>)</parameter_list> <block>{
<comment type="line">// anotherFunc body</comment>
}</block></function>
}</block></class>
</unit>`;

/*
public class myClass {
@Id
public long ID;
public myClass()
public void myFunc(int param)
@annot
private String anotherFunc(String param)
}
*/
const removedAllBodies =
`<unit xmlns="http://www.srcML.org/srcML/src" revision="0.9.5" language="Java"><class><specifier>public</specifier> class <name>myClass</name> <block>{
<decl_stmt><decl><annotation>@<name>Id</name></annotation>
<specifier>public</specifier> <type><name>long</name></type> <name>ID</name></decl>;</decl_stmt>
<constructor><specifier>public</specifier> <name>myClass</name><parameter_list>()</parameter_list> </constructor>
<function><specifier>public</specifier> <type><name>void</name></type> <name>myFunc</name><parameter_list>(<parameter><decl><type><name>int</name></type> <name>param</name></decl></parameter>)</parameter_list> </function>
<function><annotation>@<name>annot</name></annotation>
<specifier>private</specifier> <type><name>String</name></type> <name>anotherFunc</name><parameter_list>(<parameter><decl><type><name>String</name></type> <name>param</name></decl></parameter>)</parameter_list> </function>
}</block></class>
</unit>`;

/*
public class myClass {
@Id
public long ID;
public myClass()
public void myFunc(int param) {
// myFunc body
}
@annot
private String anotherFunc(String param)
}
*/
const removedFirstFuncSibBodies =
`<unit xmlns="http://www.srcML.org/srcML/src" revision="0.9.5" language="Java"><class><specifier>public</specifier> class <name>myClass</name> <block>{
<decl_stmt><decl><annotation>@<name>Id</name></annotation>
<specifier>public</specifier> <type><name>long</name></type> <name>ID</name></decl>;</decl_stmt>
<constructor><specifier>public</specifier> <name>myClass</name><parameter_list>()</parameter_list> </constructor>
<function><specifier>public</specifier> <type><name>void</name></type> <name>myFunc</name><parameter_list>(<parameter><decl><type><name>int</name></type> <name>param</name></decl></parameter>)</parameter_list> <block>{
<comment type="line">// myFunc body</comment>
}</block></function>
<function><annotation>@<name>annot</name></annotation>
<specifier>private</specifier> <type><name>String</name></type> <name>anotherFunc</name><parameter_list>(<parameter><decl><type><name>String</name></type> <name>param</name></decl></parameter>)</parameter_list> </function>
}</block></class>
</unit>`;

/*
public class myClass {
@Id
public long ID;
public myClass() {
// constructor body
this.ID = 0;
}
public void myFunc(int param)
@annot
private String anotherFunc(String param)
}
*/
const removedConstrSiblingBodies =
`<unit xmlns="http://www.srcML.org/srcML/src" revision="0.9.5" language="Java"><class><specifier>public</specifier> class <name>myClass</name> <block>{
<decl_stmt><decl><annotation>@<name>Id</name></annotation>
<specifier>public</specifier> <type><name>long</name></type> <name>ID</name></decl>;</decl_stmt>
<constructor><specifier>public</specifier> <name>myClass</name><parameter_list>()</parameter_list> <block>{
<comment type="line">// constructor body</comment>
<expr_stmt><expr><name><name>this</name><operator>.</operator><name>ID</name></name> <operator>=</operator> <literal type="number">0</literal></expr>;</expr_stmt>
}</block></constructor>
<function><specifier>public</specifier> <type><name>void</name></type> <name>myFunc</name><parameter_list>(<parameter><decl><type><name>int</name></type> <name>param</name></decl></parameter>)</parameter_list> </function>
<function><annotation>@<name>annot</name></annotation>
<specifier>private</specifier> <type><name>String</name></type> <name>anotherFunc</name><parameter_list>(<parameter><decl><type><name>String</name></type> <name>param</name></decl></parameter>)</parameter_list> </function>
}</block></class>
</unit>`;

const namespaceURI = "http://www.srcML.org/srcML/src";
const parser = new DOMParser();
const serializer = new XMLSerializer();

it("should remove function body of a given function", () => {
const input = parser.parseFromString(xmlString, "text/xml");
const functions = input.getElementsByTagNameNS(namespaceURI, 'function');
const firstFunction = functions[0];

removeFunctionBodies(firstFunction);
const output = serializer.serializeToString(input);

expect(output).toEqual(removedFirstFuncBody);
});

it("should remove function body of a given constructor", () => {
const input = parser.parseFromString(xmlString, "text/xml");
const constructors = input.getElementsByTagNameNS(namespaceURI, 'constructor');
const firstConstructor = constructors[0];

removeFunctionBodies(firstConstructor);
const output = serializer.serializeToString(input);

expect(output).toEqual(removedConstrBody);
});

it("case 2 of getSurroundingNodes, class Node", () => {
const input = parser.parseFromString(xmlString, "text/xml");
const classes = input.getElementsByTagNameNS(namespaceURI, 'class');
let node = classes[0];

// case 2: class, field
// Grab all fields and function/nested class signatures
// find the parent class
while (node && node.tagName && node.tagName.toLowerCase() !== "class" && node.parentNode) {
node = node.parentNode;
}
removeFunctionBodies(node);
const output = serializer.serializeToString(input);

expect(output).toEqual(removedAllBodies);
});

it("case 2 of getSurroundingNodes, class field Node", () => {
const input = parser.parseFromString(xmlString, "text/xml");
const decls = input.getElementsByTagNameNS(namespaceURI, 'decl_stmt');
let node = decls[0];

// case 2: class, field
// Grab all fields and function/nested class signatures
// find the parent class
while (node && node.tagName && node.tagName.toLowerCase() !== "class" && node.parentNode) {
node = node.parentNode;
}
removeFunctionBodies(node);
const output = serializer.serializeToString(input);

expect(output).toEqual(removedAllBodies);
});

it("should remove function bodies of siblings of a given function", () => {
const input = parser.parseFromString(xmlString, "text/xml");
const functions = input.getElementsByTagNameNS(namespaceURI, 'function');
const firstFunction = functions[0];

removeSiblingFunctionBodies(firstFunction);
const output = serializer.serializeToString(input);

expect(output).toEqual(removedFirstFuncSibBodies);
});

it("should remove function bodies of siblings of a given constructor", () => {
const input = parser.parseFromString(xmlString, "text/xml");
const constructors = input.getElementsByTagNameNS(namespaceURI, 'constructor');
const firstConstructor = constructors[0];

removeSiblingFunctionBodies(firstConstructor);
const output = serializer.serializeToString(input);

expect(output).toEqual(removedConstrSiblingBodies);
});

it("case 3 of getSurroundingNodes, node within a function", () => {
const input = parser.parseFromString(xmlString, "text/xml");
const comments = input.getElementsByTagNameNS(namespaceURI, 'comment');
let node = comments[1]; // body of the first function

// case 3: other, statements (starting node within method or at method signature)
// Grab all code within method and function signatures and fields adjacent/same level as method
// find the parent function
while (node && node.tagName && node.tagName.toLowerCase() !== "function" && node.parentNode) {
node = node.parentNode;
}
removeSiblingFunctionBodies(node);
const output = serializer.serializeToString(input);

expect(output).toEqual(removedFirstFuncSibBodies);
});
});

0 comments on commit 474611b

Please sign in to comment.