
com.github.dakusui.actionunit.visitors.ActionWalker Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of actionunit Show documentation
Show all versions of actionunit Show documentation
A library to build 'action' structure for testing
package com.github.dakusui.actionunit.visitors;
import com.github.dakusui.actionunit.actions.*;
import com.github.dakusui.actionunit.core.Action;
import com.github.dakusui.actionunit.helpers.Checks;
import com.github.dakusui.actionunit.visitors.reporting.Node;
import java.util.Deque;
import java.util.LinkedList;
import java.util.function.Consumer;
abstract class ActionWalker implements Action.Visitor {
private final ThreadLocal>> _current;
private Node root;
ActionWalker() {
this._current = new ThreadLocal<>();
this._current.set(new LinkedList<>());
this.root = null;
}
/**
* {@inheritDoc}
*/
@Override
public void visit(Leaf action) {
handle(
action,
leafActionConsumer()
);
}
/**
* {@inheritDoc}
*/
@Override
public void visit(Named action) {
handle(
action,
namedActionConsumer()
);
}
/**
* {@inheritDoc}
*/
@Override
public void visit(Sequential action) {
handle(
action,
sequentialActionConsumer()
);
}
/**
* {@inheritDoc}
*/
@Override
public void visit(Concurrent action) {
handle(
action,
concurrentActionConsumer()
);
}
/**
* {@inheritDoc}
*/
@Override
public void visit(ForEach action) {
handle(
action,
forEachActionConsumer()
);
}
/**
* {@inheritDoc}
*/
public void visit(While action) {
handle(
action,
whileActionConsumer()
);
}
/**
* {@inheritDoc}
*/
public void visit(When action) {
handle(
action,
whenActionConsumer()
);
}
/**
* {@inheritDoc}
*/
@Override
public void visit(Attempt action) {
handle(
action,
attemptActionConsumer()
);
}
/**
* {@inheritDoc}
*/
@Override
public void visit(TestAction action) {
handle(
action,
testActionConsumer()
);
}
/**
* {@inheritDoc}
*/
@Override
public void visit(Retry action) {
handle(
action,
retryActionConsumer()
);
}
/**
* {@inheritDoc}
*/
@Override
public void visit(TimeOut action) {
handle(
action,
timeOutActionConsumer()
);
}
protected abstract Consumer leafActionConsumer();
protected Consumer namedActionConsumer() {
return (Named named) -> named.getAction().accept(this);
}
protected Consumer sequentialActionConsumer() {
return (Sequential sequential) -> {
for (Action each : sequential) {
each.accept(this);
}
};
}
protected abstract Consumer concurrentActionConsumer();
protected abstract Consumer> forEachActionConsumer();
protected abstract Consumer> whileActionConsumer();
protected abstract Consumer> whenActionConsumer();
protected abstract Consumer> attemptActionConsumer();
protected Consumer testActionConsumer() {
return (TestAction test) -> {
test.given().accept(this);
test.when().accept(this);
test.then().accept(this);
};
}
protected abstract Consumer retryActionConsumer();
protected abstract Consumer timeOutActionConsumer();
protected final void handle(A action, Consumer handler) {
@SuppressWarnings("unchecked") Node node = toNode(
this.getCurrentNode(),
action
);
before(node);
try {
handler.accept(action);
succeeded(node);
} catch (Error | RuntimeException e) {
failed(node, e);
throw e;
} finally {
after(node);
}
}
protected Node toNode(Node parent, A action) {
return new Node<>(action, action instanceof Leaf);
}
@SuppressWarnings({ "unchecked", "WeakerAccess" })
protected void before(Node node) {
if (getCurrentPath().isEmpty()) {
pushNode(node);
root = (Node) node;
} else {
pushNode(node);
}
}
protected void succeeded(Node node) {
}
protected void failed(Node node, Throwable e) {
}
@SuppressWarnings("WeakerAccess")
protected void after(Node node) {
Checks.checkState(
this.getCurrentPath().peek() == node,
"Cannot remove %s from queue=%s", node, this.getCurrentPath()
);
popNode();
}
@SuppressWarnings("unchecked")
protected void pushNode(Node node) {
this.getCurrentPath().push((Node) node);
}
@SuppressWarnings("unchecked")
protected Node popNode() {
return (Node) this.getCurrentPath().pop();
}
protected Node getCurrentNode() {
return (Node) this.getCurrentPath().peek();
}
protected Node getRootNode() {
return root;
}
protected synchronized Deque> getCurrentPath() {
return _current.get();
}
protected void branchPath(Deque> pathSnapshot) {
this._current.set(new LinkedList<>(pathSnapshot));
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy