Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

More tests (100 % test coverage) #28

Merged
merged 18 commits into from
Sep 4, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -180,20 +180,18 @@ private static void buildNodeInfoMap(
final DiffNode parent) {
parent.forEachChild(
child -> {
if (child instanceof DiffNode) {
final DiffNode node = (DiffNode) child;
final NodeInfo obj = new NodeInfo(node, parent);
Node proto = node.getPrototype();
while (true) {
map.put(proto, obj);
if (proto instanceof PrototypeBasedNode) {
proto = ((PrototypeBasedNode) proto).getPrototype();
} else {
break;
}
final DiffNode node = (DiffNode) child;
final NodeInfo obj = new NodeInfo(node, parent);
Node proto = node.getPrototype();
while (true) {
map.put(proto, obj);
if (proto instanceof PrototypeBasedNode) {
proto = ((PrototypeBasedNode) proto).getPrototype();
} else {
break;
}
DiffTreeBuilder.buildNodeInfoMap(map, node);
}
DiffTreeBuilder.buildNodeInfoMap(map, node);
}
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,9 @@ public boolean allocate(final Node[] destination, final List<Node> source) {
final int count = source.size();
if (capacity == 0 && count == 0) {
result = true;
} else if (destination.length < capacity) {
throw new IllegalArgumentException();
} else if (capacity >= count) {
assert destination.length == capacity;
this.required = new PositionSet(false);
this.required.init();
if (count >= this.required.getCount()) {
Expand Down Expand Up @@ -128,7 +129,7 @@ private boolean fullMapping(final Node[] destination, final List<Node> source) {
result = this.required.getCount() == 0;
break;
}
result = this.bindAllNodes(destination, array) && this.required.getCount() == 0;
result = this.bindAllNodes(destination, array);
} while (false);
return result;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@

/**
* Tree converter built on a set of rules described in DSL.
*
* @since 1.0
*/
public class Adapter {
Expand Down Expand Up @@ -62,10 +61,10 @@ public Adapter(final List<Converter> converters, final Factory factory) {
* @return A converted tree or empty tree if the conversion is impossible
*/
public Node convert(final Node root) {
final MutableNode convertible = new MutableNode(root);
Node result = convertible;
final MutableNode mutable = new MutableNode(root);
Node result = mutable;
final List<MutableNode> nodes = new ArrayList<>(0);
NodeListBuilder.buildNodeList(convertible, nodes);
NodeListBuilder.buildNodeList(mutable, nodes);
for (final MutableNode original : nodes) {
boolean converted = false;
for (final Converter converter : this.converters) {
Expand All @@ -92,10 +91,10 @@ public Node convert(final Node root) {
*/
public Node partialConvert(final int variant, final Node root) {
int conversions = 0;
final MutableNode convertible = new MutableNode(root);
Node result = convertible;
final MutableNode mutable = new MutableNode(root);
Node result = mutable;
final List<MutableNode> nodes = new ArrayList<>(0);
NodeListBuilder.buildNodeList(convertible, nodes);
NodeListBuilder.buildNodeList(mutable, nodes);
for (final MutableNode original : nodes) {
final Converter converter = this.converters.get(0);
final Node transformed = converter.convert(original, this.factory);
Expand All @@ -118,9 +117,9 @@ public Node partialConvert(final int variant, final Node root) {
*/
public int calculateConversions(final Node root) {
int conversions = 0;
final MutableNode convertible = new MutableNode(root);
final MutableNode mutable = new MutableNode(root);
final List<MutableNode> nodes = new ArrayList<>(0);
NodeListBuilder.buildNodeList(convertible, nodes);
NodeListBuilder.buildNodeList(mutable, nodes);
for (final MutableNode original : nodes) {
final Converter converter = this.converters.get(0);
final Node transformed = converter.convert(original, this.factory);
Expand Down Expand Up @@ -154,7 +153,6 @@ private static Node replace(final MutableNode original,
* Creates a list from nodes.
* The list is sorted in descending order of nodes depth in the tree.
* Leaf nodes are at the beginning of the list, and the last element is the root.
*
* @since 0.2.2
*/
private static class NodeListBuilder {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,6 @@ Mapping getResult() {
* @param right Related node to the left node
*/
private void mapSubtreesWithTheSameHash(final Node left, final Node right) {
assert this.hashes.calculate(left) == this.hashes.calculate(right);
this.ltr.put(left, right);
this.rtl.put(right, left);
final int count = left.getChildCount();
Expand All @@ -139,7 +138,6 @@ private void mapSubtreesWithTheSameHash(final Node left, final Node right) {
*/
private void mapSubtreesWithDifferentHashes(final Node left, final Node right) {
final Unprocessed unprocessed = new Unprocessed(left, right);
assert unprocessed.hasNodes();
do {
if (unprocessed.onlyActionIsToInsertNodes()) {
this.insertAllNotYetMappedNodes(left, right);
Expand Down Expand Up @@ -232,7 +230,8 @@ private void replaceTwoFirstUnmappedNodes(final Node left, final Node right,
private Child findFirstUnmappedChild(final Node node) {
final int count = node.getChildCount();
Child result = null;
for (int index = 0; index < count; index = index + 1) {
int index = 0;
do {
final Node child = node.getChild(index);
if (!this.ltr.containsKey(child) && !this.rtl.containsKey(child)) {
Node before = null;
Expand All @@ -244,10 +243,9 @@ private Child findFirstUnmappedChild(final Node node) {
after = node.getChild(index + 1);
}
result = new Child(child, before, after);
break;
}
}
assert result != null;
index = index + 1;
} while (result == null);
return result;
}

Expand Down Expand Up @@ -278,14 +276,14 @@ private boolean mapTwoLastUnmappedNodes(final Node left, final Node right,
private Node findLastUnmappedChild(final Node node) {
final int count = node.getChildCount();
Node result = null;
for (int index = count - 1; index >= 0; index = index - 1) {
int index = count - 1;
do {
final Node child = node.getChild(index);
if (!this.ltr.containsKey(child) && !this.rtl.containsKey(child)) {
result = child;
break;
}
}
assert result != null;
index = index - 1;
} while (result == null);
return result;
}

Expand Down Expand Up @@ -423,22 +421,21 @@ boolean hasNodes() {
* @return Checking result, {@code true} if we can only add nodes
*/
boolean onlyActionIsToInsertNodes() {
return this.left == 0 && this.add == this.right;
return this.left == 0;
}

/**
* Analyzes a case where the only actions that are allowed are deletions.
* @return Checking result, {@code true} if we can only delete nodes
*/
boolean onlyActionIsToDeleteNodes() {
return this.right == 0 && this.delete == this.left;
return this.right == 0;
}

/**
* Notes that some child node of the right node has been recognized as an inserted node.
*/
void nodeWasInserted() {
assert this.right > 0;
this.right = this.right - 1;
if (this.add > 0) {
this.add = this.add - 1;
Expand All @@ -451,13 +448,8 @@ void nodeWasInserted() {
* Notes that some child node of the right node has been recognized as a deleted node.
*/
void nodeWasDeleted() {
assert this.left > 0;
this.left = this.left - 1;
if (this.delete > 0) {
this.delete = this.delete - 1;
} else {
this.add = this.add + 1;
}
this.delete = this.delete - 1;
}

/**
Expand All @@ -467,8 +459,6 @@ void nodeWasDeleted() {
void removeOnePair() {
this.left = this.left - 1;
this.right = this.right - 1;
assert this.right >= this.add;
assert this.left >= this.delete;
}
}

Expand Down Expand Up @@ -504,11 +494,6 @@ private static class Child {
this.before = before;
this.after = after;
}

@Override
public String toString() {
return this.node.toString();
}
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,17 @@
* @since 1.1.5
*/
public final class DefaultPatcher implements Patcher {
/**
* The instance.
*/
public static final Patcher INSTANCE = new DefaultPatcher();

/**
* Private constructor.
*/
private DefaultPatcher() {
}

@Override
public Tree patch(final Tree source, final Pattern pattern) {
final Matcher matcher = new Matcher(source);
Expand Down
64 changes: 62 additions & 2 deletions src/main/java/org/cqfn/astranaut/core/base/ChildDescriptor.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,12 @@
*/
package org.cqfn.astranaut.core.base;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
* This class describes child node within type descriptor.
*
* @since 1.0
*/
public final class ChildDescriptor {
Expand All @@ -35,7 +38,8 @@ public final class ChildDescriptor {
private final String type;

/**
* Flag that states that the child is optional.
* Flag that states that the child is optional, that is, one that can be in the list
* of child nodes but is not required.
*/
private final boolean optional;

Expand Down Expand Up @@ -73,6 +77,15 @@ public boolean isOptional() {
return this.optional;
}

/**
* Creates constructor that helps build lists of descriptors.
* @return Constructor that helps build lists of descriptors
*/
@SuppressWarnings("PMD.ProhibitPublicStaticMethods")
public static Constructor create() {
return new Constructor();
}

@Override
public String toString() {
final String result;
Expand All @@ -87,4 +100,51 @@ public String toString() {
}
return result;
}

/**
* Constructor that helps build lists of descriptors.
* @since 2.0.0
*/
public static final class Constructor {
/**
* Internal list.
*/
private final List<ChildDescriptor> list;

/**
* Constructor.
*/
private Constructor() {
this.list = new ArrayList<>(2);
}

/**
* Adds a descriptor for a node that must be in the list of child nodes.
* @param type Type name of child node
* @return The constructor itself for the continuation of the chain
*/
public Constructor required(final String type) {
this.list.add(new ChildDescriptor(type, false));
return this;
}

/**
* Adds a descriptor for an optional node, that is, one that can be in the list
* of child nodes but is not required.
* @param type Type name of child node
* @return The constructor itself for the continuation of the chain
*/
public Constructor optional(final String type) {
this.list.add(new ChildDescriptor(type, true));
return this;
}

/**
* Constructs a list of descriptors.
* @return Unmodifiable list of descriptors.
*/
public List<ChildDescriptor> build() {
return Collections.unmodifiableList(this.list);
}
}
}
17 changes: 17 additions & 0 deletions src/main/java/org/cqfn/astranaut/core/base/DraftNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import java.text.CharacterIterator;
import java.text.StringCharacterIterator;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
Expand Down Expand Up @@ -134,6 +135,22 @@ public static Node create(final String description, final Map<String, Set<Node>>
return DraftNode.create(iterator, nodes);
}

/**
* Creates a node from the type name, data, and existing child nodes..
* @param type The type name
* @param data The data (in a textual format)
* @param children The list of children
* @return A new node
*/
@SuppressWarnings("PMD.ProhibitPublicStaticMethods")
public static Node create(final String type, final String data, final Node... children) {
final DraftNode.Constructor ctor = new DraftNode.Constructor();
ctor.setName(type);
ctor.setData(data);
ctor.setChildrenList(Arrays.asList(children));
return ctor.createNode();
}

/**
* Creates a tree based on its description (recursive method).
* @param iterator Iterator by description characters
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ void testTreeWithReplacedNotUniqueNode() {
void testComplexCase() {
final Node before = DraftNode.create("X(A,B,Y(C,D,E,F,J,K))");
final Node after = DraftNode.create("X(A,G,Y(H,C,I,E,J,K))");
final DiffTreeBuilder builder = new DiffTreeBuilder(before);
final DiffTreeBuilder builder = new DiffTreeBuilder(new Tree(before));
final boolean result = builder.build(after, TopDownMapper.INSTANCE);
Assertions.assertTrue(result);
final DiffTree diff = builder.getDiffTree();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import java.util.Collections;
import java.util.Optional;
import org.cqfn.astranaut.core.base.Node;
import org.cqfn.astranaut.core.base.PrototypeBasedNode;
import org.cqfn.astranaut.core.base.Tree;
import org.cqfn.astranaut.core.example.LittleTrees;
import org.junit.jupiter.api.Assertions;
Expand All @@ -51,5 +52,8 @@ void testBaseMethods() {
.findFirst(node -> node.getTypeName().equals(target.getTypeName()));
Assertions.assertTrue(colored.isPresent());
Assertions.assertEquals(colored.get().getProperties().get(name), value);
final Node root = labeled.getRoot();
Assertions.assertTrue(root instanceof PrototypeBasedNode);
Assertions.assertSame(((PrototypeBasedNode) root).getPrototype(), original);
}
}
Loading
Loading