Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
a1a9ec6dd9
|
@ -1,4 +1,4 @@
|
||||||
package com.baeldung.automata;
|
package com.baeldung.algorithms.automata;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finite state machine.
|
* Finite state machine.
|
|
@ -1,4 +1,4 @@
|
||||||
package com.baeldung.automata;
|
package com.baeldung.algorithms.automata;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default implementation of a finite state machine.
|
* Default implementation of a finite state machine.
|
|
@ -1,4 +1,4 @@
|
||||||
package com.baeldung.automata;
|
package com.baeldung.algorithms.automata;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
|
@ -1,4 +1,4 @@
|
||||||
package com.baeldung.automata;
|
package com.baeldung.algorithms.automata;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
|
@ -1,4 +1,4 @@
|
||||||
package com.baeldung.automata;
|
package com.baeldung.algorithms.automata;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* State. Part of a finite state machine.
|
* State. Part of a finite state machine.
|
|
@ -1,4 +1,4 @@
|
||||||
package com.baeldung.automata;
|
package com.baeldung.algorithms.automata;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transition in a finite State machine.
|
* Transition in a finite State machine.
|
|
@ -0,0 +1,109 @@
|
||||||
|
package com.baeldung.algorithms.mcts.montecarlo;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.baeldung.algorithms.mcts.tictactoe.Board;
|
||||||
|
import com.baeldung.algorithms.mcts.tree.Node;
|
||||||
|
import com.baeldung.algorithms.mcts.tree.Tree;
|
||||||
|
|
||||||
|
public class MonteCarloTreeSearch {
|
||||||
|
|
||||||
|
private static final int WIN_SCORE = 10;
|
||||||
|
private int level;
|
||||||
|
private int oponent;
|
||||||
|
|
||||||
|
public MonteCarloTreeSearch() {
|
||||||
|
this.level = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getLevel() {
|
||||||
|
return level;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLevel(int level) {
|
||||||
|
this.level = level;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getMillisForCurrentLevel() {
|
||||||
|
return 2 * (this.level - 1) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Board findNextMove(Board board, int playerNo) {
|
||||||
|
long start = System.currentTimeMillis();
|
||||||
|
long end = start + 60 * getMillisForCurrentLevel();
|
||||||
|
|
||||||
|
oponent = 3 - playerNo;
|
||||||
|
Tree tree = new Tree();
|
||||||
|
Node rootNode = tree.getRoot();
|
||||||
|
rootNode.getState().setBoard(board);
|
||||||
|
rootNode.getState().setPlayerNo(oponent);
|
||||||
|
|
||||||
|
while (System.currentTimeMillis() < end) {
|
||||||
|
// Phase 1 - Selection
|
||||||
|
Node promisingNode = selectPromisingNode(rootNode);
|
||||||
|
// Phase 2 - Expansion
|
||||||
|
if (promisingNode.getState().getBoard().checkStatus() == Board.IN_PROGRESS)
|
||||||
|
expandNode(promisingNode);
|
||||||
|
|
||||||
|
// Phase 3 - Simulation
|
||||||
|
Node nodeToExplore = promisingNode;
|
||||||
|
if (promisingNode.getChildArray().size() > 0) {
|
||||||
|
nodeToExplore = promisingNode.getRandomChildNode();
|
||||||
|
}
|
||||||
|
int playoutResult = simulateRandomPlayout(nodeToExplore);
|
||||||
|
// Phase 4 - Update
|
||||||
|
backPropogation(nodeToExplore, playoutResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
Node winnerNode = rootNode.getChildWithMaxScore();
|
||||||
|
tree.setRoot(winnerNode);
|
||||||
|
return winnerNode.getState().getBoard();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Node selectPromisingNode(Node rootNode) {
|
||||||
|
Node node = rootNode;
|
||||||
|
while (node.getChildArray().size() != 0) {
|
||||||
|
node = UCT.findBestNodeWithUCT(node);
|
||||||
|
}
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void expandNode(Node node) {
|
||||||
|
List<State> possibleStates = node.getState().getAllPossibleStates();
|
||||||
|
possibleStates.forEach(state -> {
|
||||||
|
Node newNode = new Node(state);
|
||||||
|
newNode.setParent(node);
|
||||||
|
newNode.getState().setPlayerNo(node.getState().getOpponent());
|
||||||
|
node.getChildArray().add(newNode);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void backPropogation(Node nodeToExplore, int playerNo) {
|
||||||
|
Node tempNode = nodeToExplore;
|
||||||
|
while (tempNode != null) {
|
||||||
|
tempNode.getState().incrementVisit();
|
||||||
|
if (tempNode.getState().getPlayerNo() == playerNo)
|
||||||
|
tempNode.getState().addScore(WIN_SCORE);
|
||||||
|
tempNode = tempNode.getParent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int simulateRandomPlayout(Node node) {
|
||||||
|
Node tempNode = new Node(node);
|
||||||
|
State tempState = tempNode.getState();
|
||||||
|
int boardStatus = tempState.getBoard().checkStatus();
|
||||||
|
|
||||||
|
if (boardStatus == oponent) {
|
||||||
|
tempNode.getParent().getState().setWinScore(Integer.MIN_VALUE);
|
||||||
|
return boardStatus;
|
||||||
|
}
|
||||||
|
while (boardStatus == Board.IN_PROGRESS) {
|
||||||
|
tempState.togglePlayer();
|
||||||
|
tempState.randomPlay();
|
||||||
|
boardStatus = tempState.getBoard().checkStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
return boardStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,97 @@
|
||||||
|
package com.baeldung.algorithms.mcts.montecarlo;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.baeldung.algorithms.mcts.tictactoe.Board;
|
||||||
|
import com.baeldung.algorithms.mcts.tictactoe.Position;
|
||||||
|
|
||||||
|
public class State {
|
||||||
|
private Board board;
|
||||||
|
private int playerNo;
|
||||||
|
private int visitCount;
|
||||||
|
private double winScore;
|
||||||
|
|
||||||
|
public State() {
|
||||||
|
board = new Board();
|
||||||
|
}
|
||||||
|
|
||||||
|
public State(State state) {
|
||||||
|
this.board = new Board(state.getBoard());
|
||||||
|
this.playerNo = state.getPlayerNo();
|
||||||
|
this.visitCount = state.getVisitCount();
|
||||||
|
this.winScore = state.getWinScore();
|
||||||
|
}
|
||||||
|
|
||||||
|
public State(Board board) {
|
||||||
|
this.board = new Board(board);
|
||||||
|
}
|
||||||
|
|
||||||
|
Board getBoard() {
|
||||||
|
return board;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setBoard(Board board) {
|
||||||
|
this.board = board;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getPlayerNo() {
|
||||||
|
return playerNo;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setPlayerNo(int playerNo) {
|
||||||
|
this.playerNo = playerNo;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getOpponent() {
|
||||||
|
return 3 - playerNo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getVisitCount() {
|
||||||
|
return visitCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVisitCount(int visitCount) {
|
||||||
|
this.visitCount = visitCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
double getWinScore() {
|
||||||
|
return winScore;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setWinScore(double winScore) {
|
||||||
|
this.winScore = winScore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<State> getAllPossibleStates() {
|
||||||
|
List<State> possibleStates = new ArrayList<>();
|
||||||
|
List<Position> availablePositions = this.board.getEmptyPositions();
|
||||||
|
availablePositions.forEach(p -> {
|
||||||
|
State newState = new State(this.board);
|
||||||
|
newState.setPlayerNo(3 - this.playerNo);
|
||||||
|
newState.getBoard().performMove(newState.getPlayerNo(), p);
|
||||||
|
possibleStates.add(newState);
|
||||||
|
});
|
||||||
|
return possibleStates;
|
||||||
|
}
|
||||||
|
|
||||||
|
void incrementVisit() {
|
||||||
|
this.visitCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void addScore(double score) {
|
||||||
|
if (this.winScore != Integer.MIN_VALUE)
|
||||||
|
this.winScore += score;
|
||||||
|
}
|
||||||
|
|
||||||
|
void randomPlay() {
|
||||||
|
List<Position> availablePositions = this.board.getEmptyPositions();
|
||||||
|
int totalPossibilities = availablePositions.size();
|
||||||
|
int selectRandom = (int) (Math.random() * ((totalPossibilities - 1) + 1));
|
||||||
|
this.board.performMove(this.playerNo, availablePositions.get(selectRandom));
|
||||||
|
}
|
||||||
|
|
||||||
|
void togglePlayer() {
|
||||||
|
this.playerNo = 3 - this.playerNo;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
package com.baeldung.algorithms.mcts.montecarlo;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.baeldung.algorithms.mcts.tree.Node;
|
||||||
|
|
||||||
|
public class UCT {
|
||||||
|
|
||||||
|
public static double uctValue(int totalVisit, double nodeWinScore, int nodeVisit) {
|
||||||
|
if (nodeVisit == 0) {
|
||||||
|
return Integer.MAX_VALUE;
|
||||||
|
}
|
||||||
|
return (nodeWinScore / (double) nodeVisit) + 1.41 * Math.sqrt(Math.log(totalVisit) / (double) nodeVisit);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Node findBestNodeWithUCT(Node node) {
|
||||||
|
int parentVisit = node.getState().getVisitCount();
|
||||||
|
return Collections.max(
|
||||||
|
node.getChildArray(),
|
||||||
|
Comparator.comparing(c -> uctValue(parentVisit, c.getState().getWinScore(), c.getState().getVisitCount())));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,155 @@
|
||||||
|
package com.baeldung.algorithms.mcts.tictactoe;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class Board {
|
||||||
|
int[][] boardValues;
|
||||||
|
int totalMoves;
|
||||||
|
|
||||||
|
public static final int DEFAULT_BOARD_SIZE = 3;
|
||||||
|
|
||||||
|
public static final int IN_PROGRESS = -1;
|
||||||
|
public static final int DRAW = 0;
|
||||||
|
public static final int P1 = 1;
|
||||||
|
public static final int P2 = 2;
|
||||||
|
|
||||||
|
public Board() {
|
||||||
|
boardValues = new int[DEFAULT_BOARD_SIZE][DEFAULT_BOARD_SIZE];
|
||||||
|
}
|
||||||
|
|
||||||
|
public Board(int boardSize) {
|
||||||
|
boardValues = new int[boardSize][boardSize];
|
||||||
|
}
|
||||||
|
|
||||||
|
public Board(int[][] boardValues) {
|
||||||
|
this.boardValues = boardValues;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Board(int[][] boardValues, int totalMoves) {
|
||||||
|
this.boardValues = boardValues;
|
||||||
|
this.totalMoves = totalMoves;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Board(Board board) {
|
||||||
|
int boardLength = board.getBoardValues().length;
|
||||||
|
this.boardValues = new int[boardLength][boardLength];
|
||||||
|
int[][] boardValues = board.getBoardValues();
|
||||||
|
int n = boardValues.length;
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
int m = boardValues[i].length;
|
||||||
|
for (int j = 0; j < m; j++) {
|
||||||
|
this.boardValues[i][j] = boardValues[i][j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void performMove(int player, Position p) {
|
||||||
|
this.totalMoves++;
|
||||||
|
boardValues[p.getX()][p.getY()] = player;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int[][] getBoardValues() {
|
||||||
|
return boardValues;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBoardValues(int[][] boardValues) {
|
||||||
|
this.boardValues = boardValues;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int checkStatus() {
|
||||||
|
int boardSize = boardValues.length;
|
||||||
|
int maxIndex = boardSize - 1;
|
||||||
|
int[] diag1 = new int[boardSize];
|
||||||
|
int[] diag2 = new int[boardSize];
|
||||||
|
|
||||||
|
for (int i = 0; i < boardSize; i++) {
|
||||||
|
int[] row = boardValues[i];
|
||||||
|
int[] col = new int[boardSize];
|
||||||
|
for (int j = 0; j < boardSize; j++) {
|
||||||
|
col[j] = boardValues[j][i];
|
||||||
|
}
|
||||||
|
|
||||||
|
int checkRowForWin = checkForWin(row);
|
||||||
|
if(checkRowForWin!=0)
|
||||||
|
return checkRowForWin;
|
||||||
|
|
||||||
|
int checkColForWin = checkForWin(col);
|
||||||
|
if(checkColForWin!=0)
|
||||||
|
return checkColForWin;
|
||||||
|
|
||||||
|
diag1[i] = boardValues[i][i];
|
||||||
|
diag2[i] = boardValues[maxIndex - i][i];
|
||||||
|
}
|
||||||
|
|
||||||
|
int checkDia1gForWin = checkForWin(diag1);
|
||||||
|
if(checkDia1gForWin!=0)
|
||||||
|
return checkDia1gForWin;
|
||||||
|
|
||||||
|
int checkDiag2ForWin = checkForWin(diag2);
|
||||||
|
if(checkDiag2ForWin!=0)
|
||||||
|
return checkDiag2ForWin;
|
||||||
|
|
||||||
|
if (getEmptyPositions().size() > 0)
|
||||||
|
return IN_PROGRESS;
|
||||||
|
else
|
||||||
|
return DRAW;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int checkForWin(int[] row) {
|
||||||
|
boolean isEqual = true;
|
||||||
|
int size = row.length;
|
||||||
|
int previous = row[0];
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
if (previous != row[i]) {
|
||||||
|
isEqual = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
previous = row[i];
|
||||||
|
}
|
||||||
|
if(isEqual)
|
||||||
|
return previous;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void printBoard() {
|
||||||
|
int size = this.boardValues.length;
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
for (int j = 0; j < size; j++) {
|
||||||
|
System.out.print(boardValues[i][j] + " ");
|
||||||
|
}
|
||||||
|
System.out.println();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Position> getEmptyPositions() {
|
||||||
|
int size = this.boardValues.length;
|
||||||
|
List<Position> emptyPositions = new ArrayList<>();
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
for (int j = 0; j < size; j++) {
|
||||||
|
if (boardValues[i][j] == 0)
|
||||||
|
emptyPositions.add(new Position(i, j));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return emptyPositions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void printStatus() {
|
||||||
|
switch (this.checkStatus()) {
|
||||||
|
case P1:
|
||||||
|
System.out.println("Player 1 wins");
|
||||||
|
break;
|
||||||
|
case P2:
|
||||||
|
System.out.println("Player 2 wins");
|
||||||
|
break;
|
||||||
|
case DRAW:
|
||||||
|
System.out.println("Game Draw");
|
||||||
|
break;
|
||||||
|
case IN_PROGRESS:
|
||||||
|
System.out.println("Game In rogress");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
package com.baeldung.algorithms.mcts.tictactoe;
|
||||||
|
|
||||||
|
public class Position {
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
|
||||||
|
public Position() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Position(int x, int y) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getX() {
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setX(int x) {
|
||||||
|
this.x = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getY() {
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setY(int y) {
|
||||||
|
this.y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,78 @@
|
||||||
|
package com.baeldung.algorithms.mcts.tree;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.baeldung.algorithms.mcts.montecarlo.State;
|
||||||
|
|
||||||
|
public class Node {
|
||||||
|
State state;
|
||||||
|
Node parent;
|
||||||
|
List<Node> childArray;
|
||||||
|
|
||||||
|
public Node() {
|
||||||
|
this.state = new State();
|
||||||
|
childArray = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Node(State state) {
|
||||||
|
this.state = state;
|
||||||
|
childArray = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Node(State state, Node parent, List<Node> childArray) {
|
||||||
|
this.state = state;
|
||||||
|
this.parent = parent;
|
||||||
|
this.childArray = childArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Node(Node node) {
|
||||||
|
this.childArray = new ArrayList<>();
|
||||||
|
this.state = new State(node.getState());
|
||||||
|
if (node.getParent() != null)
|
||||||
|
this.parent = node.getParent();
|
||||||
|
List<Node> childArray = node.getChildArray();
|
||||||
|
for (Node child : childArray) {
|
||||||
|
this.childArray.add(new Node(child));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public State getState() {
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setState(State state) {
|
||||||
|
this.state = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Node getParent() {
|
||||||
|
return parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setParent(Node parent) {
|
||||||
|
this.parent = parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Node> getChildArray() {
|
||||||
|
return childArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setChildArray(List<Node> childArray) {
|
||||||
|
this.childArray = childArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Node getRandomChildNode() {
|
||||||
|
int noOfPossibleMoves = this.childArray.size();
|
||||||
|
int selectRandom = (int) (Math.random() * ((noOfPossibleMoves - 1) + 1));
|
||||||
|
return this.childArray.get(selectRandom);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Node getChildWithMaxScore() {
|
||||||
|
return Collections.max(this.childArray, Comparator.comparing(c -> {
|
||||||
|
return c.getState().getVisitCount();
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
package com.baeldung.algorithms.mcts.tree;
|
||||||
|
|
||||||
|
public class Tree {
|
||||||
|
Node root;
|
||||||
|
|
||||||
|
public Tree() {
|
||||||
|
root = new Node();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Tree(Node root) {
|
||||||
|
this.root = root;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Node getRoot() {
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRoot(Node root) {
|
||||||
|
this.root = root;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addChild(Node parent, Node child) {
|
||||||
|
parent.getChildArray().add(child);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
package algorithms;
|
package algorithms;
|
||||||
|
|
||||||
import com.baeldung.automata.*;
|
import com.baeldung.algorithms.automata.*;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
|
@ -0,0 +1,92 @@
|
||||||
|
package algorithms.mcts;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import com.baeldung.algorithms.mcts.montecarlo.MonteCarloTreeSearch;
|
||||||
|
import com.baeldung.algorithms.mcts.montecarlo.State;
|
||||||
|
import com.baeldung.algorithms.mcts.montecarlo.UCT;
|
||||||
|
import com.baeldung.algorithms.mcts.tictactoe.Board;
|
||||||
|
import com.baeldung.algorithms.mcts.tictactoe.Position;
|
||||||
|
import com.baeldung.algorithms.mcts.tree.Tree;
|
||||||
|
|
||||||
|
public class MCTSTest {
|
||||||
|
private Tree gameTree;
|
||||||
|
private MonteCarloTreeSearch mcts;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void initGameTree() {
|
||||||
|
gameTree = new Tree();
|
||||||
|
mcts = new MonteCarloTreeSearch();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenStats_whenGetUCTForNode_thenUCTMatchesWithManualData() {
|
||||||
|
double uctValue = 15.79;
|
||||||
|
assertEquals(UCT.uctValue(600, 300, 20), uctValue, 0.01);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void giveninitBoardState_whenGetAllPossibleStates_thenNonEmptyList() {
|
||||||
|
State initState = gameTree.getRoot().getState();
|
||||||
|
List<State> possibleStates = initState.getAllPossibleStates();
|
||||||
|
assertTrue(possibleStates.size() > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenEmptyBoard_whenPerformMove_thenLessAvailablePossitions() {
|
||||||
|
Board board = new Board();
|
||||||
|
int initAvailablePositions = board.getEmptyPositions().size();
|
||||||
|
board.performMove(Board.P1, new Position(1, 1));
|
||||||
|
int availablePositions = board.getEmptyPositions().size();
|
||||||
|
assertTrue(initAvailablePositions > availablePositions);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenEmptyBoard_whenSimulateInterAIPlay_thenGameDraw() {
|
||||||
|
Board board = new Board();
|
||||||
|
|
||||||
|
int player = Board.P1;
|
||||||
|
int totalMoves = Board.DEFAULT_BOARD_SIZE * Board.DEFAULT_BOARD_SIZE;
|
||||||
|
for (int i = 0; i < totalMoves; i++) {
|
||||||
|
board = mcts.findNextMove(board, player);
|
||||||
|
if (board.checkStatus() != -1) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
player = 3 - player;
|
||||||
|
}
|
||||||
|
int winStatus = board.checkStatus();
|
||||||
|
assertEquals(winStatus, Board.DRAW);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenEmptyBoard_whenLevel1VsLevel3_thenLevel3WinsOrDraw() {
|
||||||
|
Board board = new Board();
|
||||||
|
MonteCarloTreeSearch mcts1 = new MonteCarloTreeSearch();
|
||||||
|
mcts1.setLevel(1);
|
||||||
|
MonteCarloTreeSearch mcts3 = new MonteCarloTreeSearch();
|
||||||
|
mcts3.setLevel(3);
|
||||||
|
|
||||||
|
int player = Board.P1;
|
||||||
|
int totalMoves = Board.DEFAULT_BOARD_SIZE * Board.DEFAULT_BOARD_SIZE;
|
||||||
|
for (int i = 0; i < totalMoves; i++) {
|
||||||
|
if (player == Board.P1)
|
||||||
|
board = mcts3.findNextMove(board, player);
|
||||||
|
else
|
||||||
|
board = mcts1.findNextMove(board, player);
|
||||||
|
|
||||||
|
if (board.checkStatus() != -1) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
player = 3 - player;
|
||||||
|
}
|
||||||
|
int winStatus = board.checkStatus();
|
||||||
|
assertTrue(winStatus == Board.DRAW || winStatus == Board.P1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
### Relevant Articles:
|
||||||
|
[Introduction to Drools](http://www.baeldung.com/drools)
|
||||||
|
[Drools Using Rules from Excel Files](http://www.baeldung.com/drools-excel)
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<http-component-version>4.4.6</http-component-version>
|
<http-component-version>4.4.6</http-component-version>
|
||||||
<drools-version>7.0.0.CR1</drools-version>
|
<drools-version>7.1.0.Beta2</drools-version>
|
||||||
<apache-poi-version>3.13</apache-poi-version>
|
<apache-poi-version>3.13</apache-poi-version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,15 @@
|
||||||
package com.baeldung.drools.config;
|
package com.baeldung.drools.config;
|
||||||
|
|
||||||
|
import org.drools.decisiontable.DecisionTableProviderImpl;
|
||||||
import org.kie.api.KieServices;
|
import org.kie.api.KieServices;
|
||||||
import org.kie.api.builder.*;
|
import org.kie.api.builder.*;
|
||||||
import org.kie.api.io.KieResources;
|
import org.kie.api.io.KieResources;
|
||||||
|
import org.kie.api.io.Resource;
|
||||||
import org.kie.api.runtime.KieContainer;
|
import org.kie.api.runtime.KieContainer;
|
||||||
import org.kie.api.runtime.KieSession;
|
import org.kie.api.runtime.KieSession;
|
||||||
|
import org.kie.internal.builder.DecisionTableConfiguration;
|
||||||
|
import org.kie.internal.builder.DecisionTableInputType;
|
||||||
|
import org.kie.internal.builder.KnowledgeBuilderFactory;
|
||||||
import org.kie.internal.io.ResourceFactory;
|
import org.kie.internal.io.ResourceFactory;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
@ -64,4 +69,39 @@ public class DroolsBeanFactory {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public KieSession getKieSession(Resource dt) {
|
||||||
|
KieFileSystem kieFileSystem = kieServices.newKieFileSystem()
|
||||||
|
.write(dt);
|
||||||
|
|
||||||
|
KieBuilder kieBuilder = kieServices.newKieBuilder(kieFileSystem)
|
||||||
|
.buildAll();
|
||||||
|
|
||||||
|
KieRepository kieRepository = kieServices.getRepository();
|
||||||
|
|
||||||
|
ReleaseId krDefaultReleaseId = kieRepository.getDefaultReleaseId();
|
||||||
|
|
||||||
|
KieContainer kieContainer = kieServices.newKieContainer(krDefaultReleaseId);
|
||||||
|
|
||||||
|
KieSession ksession = kieContainer.newKieSession();
|
||||||
|
|
||||||
|
return ksession;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Can be used for debugging
|
||||||
|
* Input excelFile example: com/baeldung/drools/rules/Discount.xls
|
||||||
|
*/
|
||||||
|
public String getDrlFromExcel(String excelFile) {
|
||||||
|
DecisionTableConfiguration configuration = KnowledgeBuilderFactory.newDecisionTableConfiguration();
|
||||||
|
configuration.setInputType(DecisionTableInputType.XLS);
|
||||||
|
|
||||||
|
Resource dt = ResourceFactory.newClassPathResource(excelFile, getClass());
|
||||||
|
|
||||||
|
DecisionTableProviderImpl decisionTableProvider = new DecisionTableProviderImpl();
|
||||||
|
|
||||||
|
String drl = decisionTableProvider.loadFromResource(dt, null);
|
||||||
|
|
||||||
|
return drl;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
package com.baeldung.drools.model;
|
||||||
|
|
||||||
|
public class Customer {
|
||||||
|
|
||||||
|
private CustomerType type;
|
||||||
|
|
||||||
|
private int years;
|
||||||
|
|
||||||
|
private int discount;
|
||||||
|
|
||||||
|
public Customer(CustomerType type, int numOfYears) {
|
||||||
|
super();
|
||||||
|
this.type = type;
|
||||||
|
this.years = numOfYears;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CustomerType getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setType(CustomerType type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getYears() {
|
||||||
|
return years;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setYears(int years) {
|
||||||
|
this.years = years;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getDiscount() {
|
||||||
|
return discount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDiscount(int discount) {
|
||||||
|
this.discount = discount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum CustomerType {
|
||||||
|
INDIVIDUAL, BUSINESS;
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
|
@ -36,6 +36,7 @@ public class ApplicantServiceIntegrationTest {
|
||||||
applicantService.suggestARoleForApplicant(applicant, suggestedRole);
|
applicantService.suggestARoleForApplicant(applicant, suggestedRole);
|
||||||
assertEquals("Senior developer", suggestedRole.getRole());
|
assertEquals("Senior developer", suggestedRole.getRole());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void whenCriteriaMatching_ThenSuggestDeveloperRole() throws IOException {
|
public void whenCriteriaMatching_ThenSuggestDeveloperRole() throws IOException {
|
||||||
Applicant applicant = new Applicant("Davis", 37, 800000.0, 3);
|
Applicant applicant = new Applicant("Davis", 37, 800000.0, 3);
|
||||||
|
@ -43,6 +44,7 @@ public class ApplicantServiceIntegrationTest {
|
||||||
applicantService.suggestARoleForApplicant(applicant, suggestedRole);
|
applicantService.suggestARoleForApplicant(applicant, suggestedRole);
|
||||||
assertEquals("Developer", suggestedRole.getRole());
|
assertEquals("Developer", suggestedRole.getRole());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void whenCriteriaNotMatching_ThenNoRole() throws IOException {
|
public void whenCriteriaNotMatching_ThenNoRole() throws IOException {
|
||||||
Applicant applicant = new Applicant("John", 37, 1200000.0, 5);
|
Applicant applicant = new Applicant("John", 37, 1200000.0, 5);
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
package com.baeldung.drools.service;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.kie.api.io.Resource;
|
||||||
|
import org.kie.api.runtime.KieSession;
|
||||||
|
import org.kie.internal.io.ResourceFactory;
|
||||||
|
|
||||||
|
import com.baeldung.drools.config.DroolsBeanFactory;
|
||||||
|
import com.baeldung.drools.model.Customer;
|
||||||
|
import com.baeldung.drools.model.Customer.CustomerType;
|
||||||
|
|
||||||
|
public class DiscountExcelIntegrationTest {
|
||||||
|
|
||||||
|
private KieSession kSession;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setup() {
|
||||||
|
Resource resource = ResourceFactory.newClassPathResource("com/baeldung/drools/rules/Discount.xls", getClass());
|
||||||
|
kSession = new DroolsBeanFactory().getKieSession(resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void giveIndvidualLongStanding_whenFireRule_thenCorrectDiscount() throws Exception {
|
||||||
|
Customer customer = new Customer(CustomerType.INDIVIDUAL, 5);
|
||||||
|
kSession.insert(customer);
|
||||||
|
|
||||||
|
kSession.fireAllRules();
|
||||||
|
|
||||||
|
assertEquals(customer.getDiscount(), 15);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void giveIndvidualRecent_whenFireRule_thenCorrectDiscount() throws Exception {
|
||||||
|
|
||||||
|
Customer customer = new Customer(CustomerType.INDIVIDUAL, 1);
|
||||||
|
kSession.insert(customer);
|
||||||
|
|
||||||
|
kSession.fireAllRules();
|
||||||
|
|
||||||
|
assertEquals(customer.getDiscount(), 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void giveBusinessAny_whenFireRule_thenCorrectDiscount() throws Exception {
|
||||||
|
Customer customer = new Customer(CustomerType.BUSINESS, 0);
|
||||||
|
kSession.insert(customer);
|
||||||
|
|
||||||
|
kSession.fireAllRules();
|
||||||
|
|
||||||
|
assertEquals(customer.getDiscount(), 20);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -3,6 +3,7 @@ package com.baeldung.drools.service;
|
||||||
import com.baeldung.drools.model.Product;
|
import com.baeldung.drools.model.Product;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import static junit.framework.TestCase.assertEquals;
|
import static junit.framework.TestCase.assertEquals;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<artifactId>jmh</artifactId>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
<name>jmh</name>
|
||||||
|
<url>http://maven.apache.org</url>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||||
|
<java.version>1.8</java.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.openjdk.jmh</groupId>
|
||||||
|
<artifactId>jmh-core</artifactId>
|
||||||
|
<version>1.19</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.openjdk.jmh</groupId>
|
||||||
|
<artifactId>jmh-generator-annprocess</artifactId>
|
||||||
|
<version>1.19</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<version>3.8.1</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<archive>
|
||||||
|
<manifest>
|
||||||
|
<mainClass>com.baeldung.Application</mainClass>
|
||||||
|
</manifest>
|
||||||
|
</archive>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
|
@ -0,0 +1,14 @@
|
||||||
|
package com.baeldung;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.openjdk.jmh.Main;
|
||||||
|
import org.openjdk.jmh.runner.RunnerException;
|
||||||
|
|
||||||
|
public class Application {
|
||||||
|
|
||||||
|
public static void main(String[] args) throws RunnerException, IOException {
|
||||||
|
Main.main(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
package com.baeldung;
|
||||||
|
|
||||||
|
import org.openjdk.jmh.annotations.Benchmark;
|
||||||
|
|
||||||
|
public class BenchMark {
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public void init() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
package com.baeldung;
|
||||||
|
|
||||||
|
import junit.framework.Test;
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
import junit.framework.TestSuite;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unit test for simple App.
|
||||||
|
*/
|
||||||
|
public class AppTest
|
||||||
|
extends TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Create the test case
|
||||||
|
*
|
||||||
|
* @param testName name of the test case
|
||||||
|
*/
|
||||||
|
public AppTest( String testName )
|
||||||
|
{
|
||||||
|
super( testName );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the suite of tests being tested
|
||||||
|
*/
|
||||||
|
public static Test suite()
|
||||||
|
{
|
||||||
|
return new TestSuite( AppTest.class );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rigourous Test :-)
|
||||||
|
*/
|
||||||
|
public void testApp()
|
||||||
|
{
|
||||||
|
assertTrue( true );
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,6 +16,7 @@
|
||||||
- [Software Transactional Memory in Java Using Multiverse](http://www.baeldung.com/java-multiverse-stm)
|
- [Software Transactional Memory in Java Using Multiverse](http://www.baeldung.com/java-multiverse-stm)
|
||||||
- [Introduction to HikariCP](http://www.baeldung.com/hikaricp)
|
- [Introduction to HikariCP](http://www.baeldung.com/hikaricp)
|
||||||
- [Serenity BDD with Spring and JBehave](http://www.baeldung.com/serenity-spring-jbehave)
|
- [Serenity BDD with Spring and JBehave](http://www.baeldung.com/serenity-spring-jbehave)
|
||||||
|
- [Locality-Sensitive Hashing in Java Using Java-LSH](http://www.baeldung.com/locality-sensitive-hashing)
|
||||||
|
|
||||||
|
|
||||||
The libraries module contains examples related to small libraries that are relatively easy to use and does not require any separate module of its own.
|
The libraries module contains examples related to small libraries that are relatively easy to use and does not require any separate module of its own.
|
||||||
|
|
|
@ -70,6 +70,32 @@
|
||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.asciidoctor</groupId>
|
||||||
|
<artifactId>asciidoctor-maven-plugin</artifactId>
|
||||||
|
<version>1.5.5</version>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.asciidoctor</groupId>
|
||||||
|
<artifactId>asciidoctorj-pdf</artifactId>
|
||||||
|
<version>1.5.0-alpha.15</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>output-pdf</id>
|
||||||
|
<phase>generate-resources</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>process-asciidoc</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
<configuration>
|
||||||
|
<sourceDirectory>src/docs/asciidoc</sourceDirectory>
|
||||||
|
<outputDirectory>target/docs/asciidoc</outputDirectory>
|
||||||
|
<backend>pdf</backend>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
== Introduction Section
|
||||||
|
|
||||||
|
Hi. I'm a simple test to see if this Maven build is working. If you see me in a nice PDF, then it means everything is [red]#working#.
|
|
@ -13,7 +13,7 @@ public class AsciidoctorDemo {
|
||||||
|
|
||||||
private final Asciidoctor asciidoctor;
|
private final Asciidoctor asciidoctor;
|
||||||
|
|
||||||
public AsciidoctorDemo() {
|
AsciidoctorDemo() {
|
||||||
asciidoctor = create();
|
asciidoctor = create();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,11 +23,11 @@ public class AsciidoctorDemo {
|
||||||
.backend("pdf")
|
.backend("pdf")
|
||||||
.asMap();
|
.asMap();
|
||||||
|
|
||||||
|
|
||||||
final String outfile = asciidoctor.convertFile(new File("sample.adoc"), options);
|
final String outfile = asciidoctor.convertFile(new File("sample.adoc"), options);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String generateHTMLFromString(final String input) {
|
String generateHTMLFromString(final String input) {
|
||||||
final String output = asciidoctor.convert("Hello _Baeldung_!", new HashMap<String, Object>());
|
return asciidoctor.convert("Hello _Baeldung_!", new HashMap<String, Object>());
|
||||||
return output;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,9 +6,7 @@ import org.openjdk.jmh.Main;
|
||||||
import org.openjdk.jmh.runner.RunnerException;
|
import org.openjdk.jmh.runner.RunnerException;
|
||||||
|
|
||||||
public class JmhDemo {
|
public class JmhDemo {
|
||||||
|
|
||||||
public static void main(String[] args) throws RunnerException, IOException {
|
public static void main(String[] args) throws RunnerException, IOException {
|
||||||
Main.main(args);
|
Main.main(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
package com.baeldung.jmh.warmup;
|
||||||
|
|
||||||
|
public class MainApplication {
|
||||||
|
|
||||||
|
static {
|
||||||
|
long start = System.nanoTime();
|
||||||
|
ManualClassLoader.load();
|
||||||
|
long end = System.nanoTime();
|
||||||
|
System.out.println("Warm Up time : " + (end - start));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
long start = System.nanoTime();
|
||||||
|
ManualClassLoader.load();
|
||||||
|
long end = System.nanoTime();
|
||||||
|
System.out.println("Total time taken : " + (end - start));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
package com.baeldung.jmh.warmup;
|
||||||
|
|
||||||
|
import com.baeldung.jmh.warmup.dummy.Dummy;
|
||||||
|
|
||||||
|
public class ManualClassLoader {
|
||||||
|
|
||||||
|
public static void load() {
|
||||||
|
|
||||||
|
for (int i = 0; i < 100000; i++) {
|
||||||
|
// load all(or most) important classes
|
||||||
|
Dummy dummy = new Dummy();
|
||||||
|
dummy.m();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
package com.baeldung.jmh.warmup.dummy;
|
||||||
|
|
||||||
|
public class Dummy {
|
||||||
|
|
||||||
|
public void m() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -2,8 +2,9 @@ package com.baeldung.commons.lang3;
|
||||||
|
|
||||||
import org.apache.commons.lang3.ArrayUtils;
|
import org.apache.commons.lang3.ArrayUtils;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
import static org.junit.Assert.assertArrayEquals;
|
import static org.junit.Assert.assertArrayEquals;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
public class ArrayUtilsUnitTest {
|
public class ArrayUtilsUnitTest {
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
package com.baeldung.hikaricp;
|
package com.baeldung.hikaricp;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
public class HikariCPUnitTest {
|
public class HikariCPUnitTest {
|
||||||
|
|
|
@ -4,7 +4,15 @@ package com.baeldung.javassist;
|
||||||
import javassist.CannotCompileException;
|
import javassist.CannotCompileException;
|
||||||
import javassist.ClassPool;
|
import javassist.ClassPool;
|
||||||
import javassist.NotFoundException;
|
import javassist.NotFoundException;
|
||||||
import javassist.bytecode.*;
|
import javassist.bytecode.AccessFlag;
|
||||||
|
import javassist.bytecode.BadBytecode;
|
||||||
|
import javassist.bytecode.Bytecode;
|
||||||
|
import javassist.bytecode.ClassFile;
|
||||||
|
import javassist.bytecode.CodeAttribute;
|
||||||
|
import javassist.bytecode.CodeIterator;
|
||||||
|
import javassist.bytecode.FieldInfo;
|
||||||
|
import javassist.bytecode.MethodInfo;
|
||||||
|
import javassist.bytecode.Mnemonic;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.io.DataOutputStream;
|
import java.io.DataOutputStream;
|
||||||
|
|
|
@ -1,10 +1,5 @@
|
||||||
package com.baeldung.javatuples;
|
package com.baeldung.javatuples;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.javatuples.KeyValue;
|
import org.javatuples.KeyValue;
|
||||||
import org.javatuples.LabelValue;
|
import org.javatuples.LabelValue;
|
||||||
import org.javatuples.Pair;
|
import org.javatuples.Pair;
|
||||||
|
@ -13,6 +8,11 @@ import org.javatuples.Triplet;
|
||||||
import org.javatuples.Unit;
|
import org.javatuples.Unit;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
public class JavaTuplesUnitTest {
|
public class JavaTuplesUnitTest {
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
|
|
|
@ -93,9 +93,7 @@ public class GuideToJDOIntegrationTest {
|
||||||
Query q = pm2.newQuery("SELECT FROM " + Product.class.getName() + " WHERE price == 200");
|
Query q = pm2.newQuery("SELECT FROM " + Product.class.getName() + " WHERE price == 200");
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
List<Product> products = (List<Product>) q.execute();
|
List<Product> products = (List<Product>) q.execute();
|
||||||
Iterator<Product> iter = products.iterator();
|
for (Product p : products) {
|
||||||
while (iter.hasNext()) {
|
|
||||||
Product p = iter.next();
|
|
||||||
assertEquals("Laptop", p.name);
|
assertEquals("Laptop", p.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
package com.baeldung.jsonassert;
|
package com.baeldung.jsonassert;
|
||||||
|
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
|
||||||
|
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
@ -13,6 +11,8 @@ import org.skyscreamer.jsonassert.RegularExpressionValueMatcher;
|
||||||
import org.skyscreamer.jsonassert.comparator.ArraySizeComparator;
|
import org.skyscreamer.jsonassert.comparator.ArraySizeComparator;
|
||||||
import org.skyscreamer.jsonassert.comparator.CustomComparator;
|
import org.skyscreamer.jsonassert.comparator.CustomComparator;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
public class JsonAssertUnitTest {
|
public class JsonAssertUnitTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
package com.baeldung.junitparams;
|
package com.baeldung.junitparams;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
|
||||||
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
|
|
||||||
import junitparams.FileParameters;
|
import junitparams.FileParameters;
|
||||||
import junitparams.JUnitParamsRunner;
|
import junitparams.JUnitParamsRunner;
|
||||||
import junitparams.Parameters;
|
import junitparams.Parameters;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
@RunWith(JUnitParamsRunner.class)
|
@RunWith(JUnitParamsRunner.class)
|
||||||
public class SafeAdditionUtilTest {
|
public class SafeAdditionUtilTest {
|
||||||
|
|
|
@ -1,15 +1,5 @@
|
||||||
package com.baeldung.opennlp;
|
package com.baeldung.opennlp;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import opennlp.tools.chunker.ChunkerME;
|
import opennlp.tools.chunker.ChunkerME;
|
||||||
import opennlp.tools.chunker.ChunkerModel;
|
import opennlp.tools.chunker.ChunkerModel;
|
||||||
import opennlp.tools.cmdline.postag.POSModelLoader;
|
import opennlp.tools.cmdline.postag.POSModelLoader;
|
||||||
|
@ -31,6 +21,15 @@ import opennlp.tools.util.ObjectStream;
|
||||||
import opennlp.tools.util.PlainTextByLineStream;
|
import opennlp.tools.util.PlainTextByLineStream;
|
||||||
import opennlp.tools.util.Span;
|
import opennlp.tools.util.Span;
|
||||||
import opennlp.tools.util.TrainingParameters;
|
import opennlp.tools.util.TrainingParameters;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
public class OpenNLPTests {
|
public class OpenNLPTests {
|
||||||
|
|
||||||
|
@ -48,8 +47,6 @@ public class OpenNLPTests {
|
||||||
String sentences[] = sdetector.sentDetect(text);
|
String sentences[] = sdetector.sentDetect(text);
|
||||||
assertEquals(4, sentences.length);
|
assertEquals(4, sentences.length);
|
||||||
is.close();
|
is.close();
|
||||||
} catch (FileNotFoundException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
@ -68,8 +65,6 @@ public class OpenNLPTests {
|
||||||
String[] names = Span.spansToStrings(nameSpans, sentence);
|
String[] names = Span.spansToStrings(nameSpans, sentence);
|
||||||
assertEquals(1, names.length);
|
assertEquals(1, names.length);
|
||||||
assertEquals("James Jordan", names[0]);
|
assertEquals("James Jordan", names[0]);
|
||||||
} catch (FileNotFoundException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
@ -88,8 +83,6 @@ public class OpenNLPTests {
|
||||||
String[] locations = Span.spansToStrings(locationSpans, sentence);
|
String[] locations = Span.spansToStrings(locationSpans, sentence);
|
||||||
assertEquals(1, locations.length);
|
assertEquals(1, locations.length);
|
||||||
assertEquals("Oklahoma", locations[0]);
|
assertEquals("Oklahoma", locations[0]);
|
||||||
} catch (FileNotFoundException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,9 +2,6 @@ package com.baeldung.serenity;
|
||||||
|
|
||||||
import net.serenitybdd.jbehave.SerenityStory;
|
import net.serenitybdd.jbehave.SerenityStory;
|
||||||
|
|
||||||
/**
|
|
||||||
* @author aiet
|
|
||||||
*/
|
|
||||||
public class GithubUserProfilePayloadIntegrationTest extends SerenityStory {
|
public class GithubUserProfilePayloadIntegrationTest extends SerenityStory {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,13 +13,11 @@ import static org.hamcrest.CoreMatchers.containsString;
|
||||||
import static org.junit.Assert.assertThat;
|
import static org.junit.Assert.assertThat;
|
||||||
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;
|
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;
|
||||||
|
|
||||||
/**
|
|
||||||
* @author aiet
|
|
||||||
*/
|
|
||||||
@RunWith(SerenityRunner.class)
|
@RunWith(SerenityRunner.class)
|
||||||
public class GoogleSearchLiveTest {
|
public class GoogleSearchLiveTest {
|
||||||
|
|
||||||
@Managed(driver = "chrome") private WebDriver browser;
|
@Managed(driver = "chrome")
|
||||||
|
private WebDriver browser;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void whenGoogleBaeldungThenShouldSeeEugen() {
|
public void whenGoogleBaeldungThenShouldSeeEugen() {
|
||||||
|
|
|
@ -7,15 +7,13 @@ import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.openqa.selenium.WebDriver;
|
import org.openqa.selenium.WebDriver;
|
||||||
|
|
||||||
/**
|
|
||||||
* @author aiet
|
|
||||||
*/
|
|
||||||
@RunWith(SerenityRunner.class)
|
@RunWith(SerenityRunner.class)
|
||||||
public class GoogleSearchPageObjectLiveTest {
|
public class GoogleSearchPageObjectLiveTest {
|
||||||
|
|
||||||
@Managed(driver = "chrome") private WebDriver browser;
|
@Managed(driver = "chrome")
|
||||||
|
private WebDriver browser;
|
||||||
|
|
||||||
GoogleSearchPageObject googleSearch;
|
private GoogleSearchPageObject googleSearch;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void whenGoogleBaeldungThenShouldSeeEugen() {
|
public void whenGoogleBaeldungThenShouldSeeEugen() {
|
||||||
|
|
|
@ -12,19 +12,20 @@ import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.openqa.selenium.WebDriver;
|
import org.openqa.selenium.WebDriver;
|
||||||
|
|
||||||
import static net.serenitybdd.screenplay.GivenWhenThen.*;
|
import static net.serenitybdd.screenplay.GivenWhenThen.givenThat;
|
||||||
|
import static net.serenitybdd.screenplay.GivenWhenThen.seeThat;
|
||||||
|
import static net.serenitybdd.screenplay.GivenWhenThen.then;
|
||||||
|
import static net.serenitybdd.screenplay.GivenWhenThen.when;
|
||||||
import static org.hamcrest.CoreMatchers.containsString;
|
import static org.hamcrest.CoreMatchers.containsString;
|
||||||
import static org.hamcrest.CoreMatchers.hasItem;
|
import static org.hamcrest.CoreMatchers.hasItem;
|
||||||
|
|
||||||
/**
|
|
||||||
* Unit test for simple App.
|
|
||||||
*/
|
|
||||||
@RunWith(SerenityRunner.class)
|
@RunWith(SerenityRunner.class)
|
||||||
public class GoogleSearchScreenplayLiveTest {
|
public class GoogleSearchScreenplayLiveTest {
|
||||||
|
|
||||||
@Managed(driver = "chrome") WebDriver browser;
|
@Managed(driver = "chrome")
|
||||||
|
private WebDriver browser;
|
||||||
|
|
||||||
Actor kitty = Actor.named("kitty");
|
private Actor kitty = Actor.named("kitty");
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setup() {
|
public void setup() {
|
||||||
|
|
|
@ -16,7 +16,8 @@ import static com.baeldung.serenity.membership.MemberGrade.Silver;
|
||||||
@RunWith(SerenityRunner.class)
|
@RunWith(SerenityRunner.class)
|
||||||
public class MemberStatusIntegrationTest {
|
public class MemberStatusIntegrationTest {
|
||||||
|
|
||||||
@Steps MemberStatusSteps memberSteps;
|
@Steps
|
||||||
|
private MemberStatusSteps memberSteps;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void membersShouldStartWithBronzeStatus() {
|
public void membersShouldStartWithBronzeStatus() {
|
||||||
|
|
|
@ -8,25 +8,22 @@ import java.io.IOException;
|
||||||
import static net.serenitybdd.rest.SerenityRest.rest;
|
import static net.serenitybdd.rest.SerenityRest.rest;
|
||||||
import static net.serenitybdd.rest.SerenityRest.then;
|
import static net.serenitybdd.rest.SerenityRest.then;
|
||||||
|
|
||||||
/**
|
class GithubRestAssuredUserAPISteps {
|
||||||
* @author aiet
|
|
||||||
*/
|
|
||||||
public class GithubRestAssuredUserAPISteps {
|
|
||||||
|
|
||||||
private String api;
|
private String api;
|
||||||
|
|
||||||
@Step("Given the github REST API for user profile")
|
@Step("Given the github REST API for user profile")
|
||||||
public void withUserProfileAPIEndpoint() {
|
void withUserProfileAPIEndpoint() {
|
||||||
api = "https://api.github.com/users/{username}";
|
api = "https://api.github.com/users/{username}";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Step("When looking for {0} via the api")
|
@Step("When looking for {0} via the api")
|
||||||
public void getProfileOfUser(String username) throws IOException {
|
void getProfileOfUser(String username) throws IOException {
|
||||||
rest().get(api, username);
|
rest().get(api, username);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Step("Then there should be a login field with value {0} in payload of user {0}")
|
@Step("Then there should be a login field with value {0} in payload of user {0}")
|
||||||
public void profilePayloadShouldContainLoginValue(String username) {
|
void profilePayloadShouldContainLoginValue(String username) {
|
||||||
then().body("login", Matchers.equalTo(username));
|
then().body("login", Matchers.equalTo(username));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,9 +14,6 @@ import java.io.IOException;
|
||||||
|
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
|
||||||
/**
|
|
||||||
* @author aiet
|
|
||||||
*/
|
|
||||||
public class GithubRestUserAPISteps {
|
public class GithubRestUserAPISteps {
|
||||||
|
|
||||||
private String api;
|
private String api;
|
||||||
|
|
|
@ -9,11 +9,8 @@ import java.io.IOException;
|
||||||
|
|
||||||
public class GithubUserProfilePayloadStepDefinitions {
|
public class GithubUserProfilePayloadStepDefinitions {
|
||||||
|
|
||||||
// @Steps
|
|
||||||
// GithubRestUserAPISteps userAPISteps;
|
|
||||||
|
|
||||||
@Steps
|
@Steps
|
||||||
GithubRestAssuredUserAPISteps userAPISteps;
|
private GithubRestAssuredUserAPISteps userAPISteps;
|
||||||
|
|
||||||
@Given("github user profile api")
|
@Given("github user profile api")
|
||||||
public void givenGithubUserProfileApi() {
|
public void givenGithubUserProfileApi() {
|
||||||
|
|
|
@ -6,12 +6,9 @@ import net.thucydides.core.annotations.Step;
|
||||||
import static org.hamcrest.CoreMatchers.equalTo;
|
import static org.hamcrest.CoreMatchers.equalTo;
|
||||||
import static org.junit.Assert.assertThat;
|
import static org.junit.Assert.assertThat;
|
||||||
|
|
||||||
/**
|
|
||||||
* @author aiet
|
|
||||||
*/
|
|
||||||
public class MemberStatusSteps {
|
public class MemberStatusSteps {
|
||||||
|
|
||||||
Member member;
|
private Member member;
|
||||||
|
|
||||||
@Step("Given a member has {0} points")
|
@Step("Given a member has {0} points")
|
||||||
public void aMemberHasPointsOf(int points) {
|
public void aMemberHasPointsOf(int points) {
|
||||||
|
|
|
@ -10,15 +10,14 @@ import static java.util.concurrent.TimeUnit.SECONDS;
|
||||||
import static org.hamcrest.CoreMatchers.containsString;
|
import static org.hamcrest.CoreMatchers.containsString;
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
|
||||||
/**
|
|
||||||
* @author aiet
|
|
||||||
*/
|
|
||||||
@DefaultUrl("https://www.google.com/ncr")
|
@DefaultUrl("https://www.google.com/ncr")
|
||||||
public class GoogleSearchPageObject extends PageObject {
|
public class GoogleSearchPageObject extends PageObject {
|
||||||
|
|
||||||
@FindBy(name = "q") private WebElement search;
|
@FindBy(name = "q")
|
||||||
|
private WebElement search;
|
||||||
|
|
||||||
@FindBy(css = "._ksh") private WebElement result;
|
@FindBy(css = "._ksh")
|
||||||
|
private WebElement result;
|
||||||
|
|
||||||
public void searchFor(String keyword) {
|
public void searchFor(String keyword) {
|
||||||
search.sendKeys(keyword, Keys.ENTER);
|
search.sendKeys(keyword, Keys.ENTER);
|
||||||
|
|
|
@ -8,13 +8,13 @@ import net.thucydides.core.annotations.DefaultUrl;
|
||||||
* @author baoqiang
|
* @author baoqiang
|
||||||
*/
|
*/
|
||||||
@DefaultUrl("https://www.google.com/ncr")
|
@DefaultUrl("https://www.google.com/ncr")
|
||||||
public class GoogleSearchPage extends PageObject {
|
class GoogleSearchPage extends PageObject {
|
||||||
|
|
||||||
public static final Target SEARCH_RESULT_TITLES = Target
|
static final Target SEARCH_RESULT_TITLES = Target
|
||||||
.the("search results")
|
.the("search results")
|
||||||
.locatedBy("._ksh");
|
.locatedBy("._ksh");
|
||||||
|
|
||||||
public static final Target SEARCH_INPUT_BOX = Target
|
static final Target SEARCH_INPUT_BOX = Target
|
||||||
.the("search input box")
|
.the("search input box")
|
||||||
.locatedBy("#lst-ib");
|
.locatedBy("#lst-ib");
|
||||||
|
|
||||||
|
|
|
@ -6,9 +6,6 @@ import net.serenitybdd.screenplay.questions.Text;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
|
||||||
* @author baoqiang
|
|
||||||
*/
|
|
||||||
public class GoogleSearchResults implements Question<List<String>> {
|
public class GoogleSearchResults implements Question<List<String>> {
|
||||||
|
|
||||||
public static Question<List<String>> displayed() {
|
public static Question<List<String>> displayed() {
|
||||||
|
|
|
@ -7,9 +7,6 @@ import net.serenitybdd.screenplay.actions.Enter;
|
||||||
import net.thucydides.core.annotations.Step;
|
import net.thucydides.core.annotations.Step;
|
||||||
import org.openqa.selenium.Keys;
|
import org.openqa.selenium.Keys;
|
||||||
|
|
||||||
/**
|
|
||||||
* @author baoqiang
|
|
||||||
*/
|
|
||||||
public class SearchForKeyword implements Task {
|
public class SearchForKeyword implements Task {
|
||||||
|
|
||||||
@Step("{0} searches for '#keyword'")
|
@Step("{0} searches for '#keyword'")
|
||||||
|
|
|
@ -7,9 +7,6 @@ import net.thucydides.core.annotations.Step;
|
||||||
|
|
||||||
import static net.serenitybdd.screenplay.Tasks.instrumented;
|
import static net.serenitybdd.screenplay.Tasks.instrumented;
|
||||||
|
|
||||||
/**
|
|
||||||
* @author baoqiang
|
|
||||||
*/
|
|
||||||
public class StartWith implements Task {
|
public class StartWith implements Task {
|
||||||
|
|
||||||
public static StartWith googleSearchPage() {
|
public static StartWith googleSearchPage() {
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
package com.baeldung.stm;
|
package com.baeldung.stm;
|
||||||
|
|
||||||
|
|
||||||
import org.junit.Rule;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.rules.ExpectedException;
|
|
||||||
|
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
|
|
|
@ -7,3 +7,4 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring
|
||||||
|
|
||||||
- [Concurrent Test Execution in Spring 5](http://www.baeldung.com/spring-5-concurrent-tests)
|
- [Concurrent Test Execution in Spring 5](http://www.baeldung.com/spring-5-concurrent-tests)
|
||||||
- [Introduction to the Functional Web Framework in Spring 5](http://www.baeldung.com/spring-5-functional-web)
|
- [Introduction to the Functional Web Framework in Spring 5](http://www.baeldung.com/spring-5-functional-web)
|
||||||
|
- [Exploring the Spring MVC URL Matching Improvements](http://www.baeldung.com/spring-mvc-url-matching)
|
||||||
|
|
|
@ -177,6 +177,7 @@
|
||||||
<junit.platform.version>1.0.0-M4</junit.platform.version>
|
<junit.platform.version>1.0.0-M4</junit.platform.version>
|
||||||
<junit.jupiter.version>5.0.0-M4</junit.jupiter.version>
|
<junit.jupiter.version>5.0.0-M4</junit.jupiter.version>
|
||||||
<maven-surefire-plugin.version>2.20</maven-surefire-plugin.version>
|
<maven-surefire-plugin.version>2.20</maven-surefire-plugin.version>
|
||||||
|
<spring.version>5.0.0.RC2</spring.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -2,8 +2,10 @@ package com.baeldung;
|
||||||
|
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.context.annotation.ComponentScan;
|
||||||
|
|
||||||
@SpringBootApplication
|
@SpringBootApplication
|
||||||
|
@ComponentScan(basePackages = {"com.baeldung.web"})
|
||||||
public class Spring5Application {
|
public class Spring5Application {
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
package com.baeldung.functional;
|
||||||
|
|
||||||
|
import static org.springframework.web.reactive.function.BodyInserters.fromObject;
|
||||||
|
import static org.springframework.web.reactive.function.server.RequestPredicates.GET;
|
||||||
|
import static org.springframework.web.reactive.function.server.RouterFunctions.route;
|
||||||
|
import static org.springframework.web.reactive.function.server.RouterFunctions.toHttpHandler;
|
||||||
|
import static org.springframework.web.reactive.function.server.ServerResponse.ok;
|
||||||
|
|
||||||
|
import org.apache.catalina.Context;
|
||||||
|
import org.apache.catalina.startup.Tomcat;
|
||||||
|
import org.springframework.boot.web.embedded.tomcat.TomcatWebServer;
|
||||||
|
import org.springframework.boot.web.server.WebServer;
|
||||||
|
import org.springframework.core.io.ClassPathResource;
|
||||||
|
import org.springframework.http.server.reactive.HttpHandler;
|
||||||
|
import org.springframework.http.server.reactive.ServletHttpHandlerAdapter;
|
||||||
|
import org.springframework.web.reactive.function.server.RouterFunction;
|
||||||
|
import org.springframework.web.reactive.function.server.RouterFunctions;
|
||||||
|
import org.springframework.web.reactive.function.server.ServerResponse;
|
||||||
|
import org.springframework.web.server.WebHandler;
|
||||||
|
import org.springframework.web.server.adapter.WebHttpHandlerBuilder;
|
||||||
|
|
||||||
|
public class ExploreSpring5URLPatternUsingRouterFunctions {
|
||||||
|
|
||||||
|
private RouterFunction<ServerResponse> routingFunction() {
|
||||||
|
|
||||||
|
return route(GET("/p?ths"), serverRequest -> ok().body(fromObject("/p?ths"))).andRoute(GET("/test/{*id}"), serverRequest -> ok().body(fromObject(serverRequest.pathVariable("id"))))
|
||||||
|
.andRoute(GET("/*card"), serverRequest -> ok().body(fromObject("/*card path was accessed")))
|
||||||
|
.andRoute(GET("/{var1}_{var2}"), serverRequest -> ok().body(fromObject(serverRequest.pathVariable("var1") + " , " + serverRequest.pathVariable("var2"))))
|
||||||
|
.andRoute(GET("/{baeldung:[a-z]+}"), serverRequest -> ok().body(fromObject("/{baeldung:[a-z]+} was accessed and baeldung=" + serverRequest.pathVariable("baeldung"))))
|
||||||
|
.and(RouterFunctions.resources("/files/{*filepaths}", new ClassPathResource("files/")));
|
||||||
|
}
|
||||||
|
|
||||||
|
WebServer start() throws Exception {
|
||||||
|
WebHandler webHandler = (WebHandler) toHttpHandler(routingFunction());
|
||||||
|
HttpHandler httpHandler = WebHttpHandlerBuilder.webHandler(webHandler)
|
||||||
|
.prependFilter(new IndexRewriteFilter())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Tomcat tomcat = new Tomcat();
|
||||||
|
tomcat.setHostname("localhost");
|
||||||
|
tomcat.setPort(9090);
|
||||||
|
Context rootContext = tomcat.addContext("", System.getProperty("java.io.tmpdir"));
|
||||||
|
ServletHttpHandlerAdapter servlet = new ServletHttpHandlerAdapter(httpHandler);
|
||||||
|
Tomcat.addServlet(rootContext, "httpHandlerServlet", servlet);
|
||||||
|
rootContext.addServletMappingDecoded("/", "httpHandlerServlet");
|
||||||
|
|
||||||
|
TomcatWebServer server = new TomcatWebServer(tomcat);
|
||||||
|
server.start();
|
||||||
|
return server;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
try {
|
||||||
|
new FunctionalWebApplication().start();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -15,6 +15,7 @@ import org.springframework.security.config.annotation.web.configuration.WebSecur
|
||||||
import org.springframework.web.reactive.function.server.RouterFunction;
|
import org.springframework.web.reactive.function.server.RouterFunction;
|
||||||
import org.springframework.web.reactive.function.server.RouterFunctions;
|
import org.springframework.web.reactive.function.server.RouterFunctions;
|
||||||
import org.springframework.web.reactive.function.server.ServerResponse;
|
import org.springframework.web.reactive.function.server.ServerResponse;
|
||||||
|
import org.springframework.web.server.WebHandler;
|
||||||
import org.springframework.web.server.adapter.WebHttpHandlerBuilder;
|
import org.springframework.web.server.adapter.WebHttpHandlerBuilder;
|
||||||
import reactor.core.publisher.Flux;
|
import reactor.core.publisher.Flux;
|
||||||
|
|
||||||
|
@ -58,7 +59,7 @@ public class FunctionalSpringBootApplication {
|
||||||
@Bean
|
@Bean
|
||||||
public ServletRegistrationBean servletRegistrationBean() throws Exception {
|
public ServletRegistrationBean servletRegistrationBean() throws Exception {
|
||||||
HttpHandler httpHandler = WebHttpHandlerBuilder
|
HttpHandler httpHandler = WebHttpHandlerBuilder
|
||||||
.webHandler(toHttpHandler(routingFunction()))
|
.webHandler((WebHandler) toHttpHandler(routingFunction()))
|
||||||
.prependFilter(new IndexRewriteFilter())
|
.prependFilter(new IndexRewriteFilter())
|
||||||
.build();
|
.build();
|
||||||
ServletRegistrationBean registrationBean = new ServletRegistrationBean<>(new RootServlet(httpHandler), "/");
|
ServletRegistrationBean registrationBean = new ServletRegistrationBean<>(new RootServlet(httpHandler), "/");
|
||||||
|
|
|
@ -50,7 +50,7 @@ public class FunctionalWebApplication {
|
||||||
}
|
}
|
||||||
|
|
||||||
WebServer start() throws Exception {
|
WebServer start() throws Exception {
|
||||||
WebHandler webHandler = toHttpHandler(routingFunction());
|
WebHandler webHandler = (WebHandler) toHttpHandler(routingFunction());
|
||||||
HttpHandler httpHandler = WebHttpHandlerBuilder
|
HttpHandler httpHandler = WebHttpHandlerBuilder
|
||||||
.webHandler(webHandler)
|
.webHandler(webHandler)
|
||||||
.prependFilter(new IndexRewriteFilter())
|
.prependFilter(new IndexRewriteFilter())
|
||||||
|
|
|
@ -19,7 +19,7 @@ class IndexRewriteFilter implements WebFilter {
|
||||||
.mutate()
|
.mutate()
|
||||||
.request(builder -> builder
|
.request(builder -> builder
|
||||||
.method(request.getMethod())
|
.method(request.getMethod())
|
||||||
.contextPath(request.getContextPath())
|
.contextPath(request.getPath().toString())
|
||||||
.path("/test"))
|
.path("/test"))
|
||||||
.build());
|
.build());
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,12 +23,13 @@ import static org.springframework.web.reactive.function.server.RequestPredicates
|
||||||
import static org.springframework.web.reactive.function.server.RouterFunctions.route;
|
import static org.springframework.web.reactive.function.server.RouterFunctions.route;
|
||||||
import static org.springframework.web.reactive.function.server.RouterFunctions.toHttpHandler;
|
import static org.springframework.web.reactive.function.server.RouterFunctions.toHttpHandler;
|
||||||
import static org.springframework.web.reactive.function.server.ServerResponse.ok;
|
import static org.springframework.web.reactive.function.server.ServerResponse.ok;
|
||||||
|
import org.springframework.web.server.WebHandler;
|
||||||
|
|
||||||
public class RootServlet extends ServletHttpHandlerAdapter {
|
public class RootServlet extends ServletHttpHandlerAdapter {
|
||||||
|
|
||||||
public RootServlet() {
|
public RootServlet() {
|
||||||
this(WebHttpHandlerBuilder
|
this(WebHttpHandlerBuilder
|
||||||
.webHandler(toHttpHandler(routingFunction()))
|
.webHandler((WebHandler) toHttpHandler(routingFunction()))
|
||||||
.prependFilter(new IndexRewriteFilter())
|
.prependFilter(new IndexRewriteFilter())
|
||||||
.build());
|
.build());
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
package com.baeldung.web;
|
||||||
|
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
public class PathPatternController {
|
||||||
|
|
||||||
|
@GetMapping("/spring5/{*id}")
|
||||||
|
public String URIVariableHandler(@PathVariable String id) {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/s?ring5")
|
||||||
|
public String wildcardTakingExactlyOneChar() {
|
||||||
|
return "/s?ring5";
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/spring5/*id")
|
||||||
|
public String wildcardTakingZeroOrMoreChar() {
|
||||||
|
return "/spring5/*id";
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/resources/**")
|
||||||
|
public String wildcardTakingZeroOrMorePathSegments() {
|
||||||
|
return "/resources/**";
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/{baeldung:[a-z]+}")
|
||||||
|
public String regexInPathVariable(@PathVariable String baeldung) {
|
||||||
|
return baeldung;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/{var1}_{var2}")
|
||||||
|
public String multiplePathVariablesInSameSegment(@PathVariable String var1, @PathVariable String var2) {
|
||||||
|
return "Two variables are var1=" + var1 + " and var2=" + var2;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
test
|
|
@ -15,9 +15,6 @@ import java.util.concurrent.TimeUnit;
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.Assert.assertNotNull;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
/**
|
|
||||||
* @author aiet
|
|
||||||
*/
|
|
||||||
@RunWith(SpringRunner.class)
|
@RunWith(SpringRunner.class)
|
||||||
@ContextConfiguration(classes = Spring5JUnit4ConcurrentIntegrationTest.SimpleConfiguration.class)
|
@ContextConfiguration(classes = Spring5JUnit4ConcurrentIntegrationTest.SimpleConfiguration.class)
|
||||||
public class Spring5JUnit4ConcurrentIntegrationTest implements ApplicationContextAware, InitializingBean {
|
public class Spring5JUnit4ConcurrentIntegrationTest implements ApplicationContextAware, InitializingBean {
|
||||||
|
|
|
@ -0,0 +1,110 @@
|
||||||
|
package com.baeldung.functional;
|
||||||
|
|
||||||
|
import org.junit.AfterClass;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.springframework.boot.web.server.WebServer;
|
||||||
|
import org.springframework.test.web.reactive.server.WebTestClient;
|
||||||
|
|
||||||
|
public class ExploreSpring5URLPatternUsingRouterFunctionsTest {
|
||||||
|
|
||||||
|
private static WebTestClient client;
|
||||||
|
private static WebServer server;
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void setup() throws Exception {
|
||||||
|
server = new ExploreSpring5URLPatternUsingRouterFunctions().start();
|
||||||
|
client = WebTestClient.bindToServer()
|
||||||
|
.baseUrl("http://localhost:" + server.getPort())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterClass
|
||||||
|
public static void destroy() {
|
||||||
|
server.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenRouter_whenGetPathWithSingleCharWildcard_thenGotPathPattern() throws Exception {
|
||||||
|
client.get()
|
||||||
|
.uri("/paths")
|
||||||
|
.exchange()
|
||||||
|
.expectStatus()
|
||||||
|
.isOk()
|
||||||
|
.expectBody(String.class)
|
||||||
|
.isEqualTo("/p?ths");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenRouter_whenMultipleURIVariablePattern_thenGotPathVariable() throws Exception {
|
||||||
|
client.get()
|
||||||
|
.uri("/test/ab/cd")
|
||||||
|
.exchange()
|
||||||
|
.expectStatus()
|
||||||
|
.isOk()
|
||||||
|
.expectBody(String.class)
|
||||||
|
.isEqualTo("/ab/cd");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenRouter_whenGetMultipleCharWildcard_thenGotPathPattern() throws Exception {
|
||||||
|
|
||||||
|
client.get()
|
||||||
|
.uri("/wildcard")
|
||||||
|
.exchange()
|
||||||
|
.expectStatus()
|
||||||
|
.isOk()
|
||||||
|
.expectBody(String.class)
|
||||||
|
.isEqualTo("/*card path was accessed");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenRouter_whenGetMultiplePathVaribleInSameSegment_thenGotPathVariables() throws Exception {
|
||||||
|
|
||||||
|
client.get()
|
||||||
|
.uri("/baeldung_tutorial")
|
||||||
|
.exchange()
|
||||||
|
.expectStatus()
|
||||||
|
.isOk()
|
||||||
|
.expectBody(String.class)
|
||||||
|
.isEqualTo("baeldung , tutorial");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenRouter_whenGetRegexInPathVarible_thenGotPathVariable() throws Exception {
|
||||||
|
|
||||||
|
client.get()
|
||||||
|
.uri("/abcd")
|
||||||
|
.exchange()
|
||||||
|
.expectStatus()
|
||||||
|
.isOk()
|
||||||
|
.expectBody(String.class)
|
||||||
|
.isEqualTo("/{baeldung:[a-z]+} was accessed and baeldung=abcd");
|
||||||
|
|
||||||
|
client.get()
|
||||||
|
.uri("/1234")
|
||||||
|
.exchange()
|
||||||
|
.expectStatus()
|
||||||
|
.is4xxClientError();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenResources_whenAccess_thenGot() throws Exception {
|
||||||
|
client.get()
|
||||||
|
.uri("/files/test/test.txt")
|
||||||
|
.exchange()
|
||||||
|
.expectStatus()
|
||||||
|
.isOk()
|
||||||
|
.expectBody(String.class)
|
||||||
|
.isEqualTo("test");
|
||||||
|
|
||||||
|
client.get()
|
||||||
|
.uri("/files/hello.txt")
|
||||||
|
.exchange()
|
||||||
|
.expectStatus()
|
||||||
|
.isOk()
|
||||||
|
.expectBody(String.class)
|
||||||
|
.isEqualTo("hello");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -8,7 +8,6 @@ import org.springframework.core.io.ClassPathResource;
|
||||||
import org.springframework.core.io.Resource;
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.test.web.reactive.server.WebTestClient;
|
import org.springframework.test.web.reactive.server.WebTestClient;
|
||||||
|
|
||||||
import org.springframework.util.LinkedMultiValueMap;
|
import org.springframework.util.LinkedMultiValueMap;
|
||||||
import org.springframework.util.MultiValueMap;
|
import org.springframework.util.MultiValueMap;
|
||||||
import org.springframework.web.reactive.function.BodyInserters;
|
import org.springframework.web.reactive.function.BodyInserters;
|
||||||
|
|
|
@ -16,10 +16,10 @@ import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
class Spring5JUnit5ComposedAnnotationIntegrationTest {
|
class Spring5JUnit5ComposedAnnotationIntegrationTest {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
Task task;
|
private Task task;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
List<Task> tasks;
|
private List<Task> tasks;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("ApplicationContext injected into method")
|
@DisplayName("ApplicationContext injected into method")
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package com.baeldung.jupiter;
|
package com.baeldung.jupiter;
|
||||||
|
|
||||||
import com.baeldung.web.reactive.Task;
|
import com.baeldung.web.reactive.Task;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
|
@ -10,14 +10,12 @@ import org.springframework.test.context.ContextConfiguration;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
@ExtendWith(SpringExtension.class)
|
@ExtendWith(SpringExtension.class)
|
||||||
@ContextConfiguration(classes = TestConfig.class)
|
@ContextConfiguration(classes = TestConfig.class)
|
||||||
class Spring5JUnit5IntegrationTest {
|
class Spring5JUnit5IntegrationTest {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
Task task;
|
private Task task;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void givenAMethodName_whenInjecting_thenApplicationContextInjectedIntoMetho(ApplicationContext applicationContext) {
|
void givenAMethodName_whenInjecting_thenApplicationContextInjectedIntoMetho(ApplicationContext applicationContext) {
|
||||||
|
|
|
@ -7,10 +7,10 @@ import org.junit.jupiter.api.Test;
|
||||||
import org.junit.runner.Computer;
|
import org.junit.runner.Computer;
|
||||||
import org.junit.runner.JUnitCore;
|
import org.junit.runner.JUnitCore;
|
||||||
|
|
||||||
public class Spring5JUnit5ParallelIntegrationTest {
|
class Spring5JUnit5ParallelIntegrationTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void givenTwoTestClasses_whenJUnitRunParallel_thenTheTestsExecutingParallel() {
|
void givenTwoTestClasses_whenJUnitRunParallel_thenTheTestsExecutingParallel() {
|
||||||
final Class<?>[] classes = {
|
final Class<?>[] classes = {
|
||||||
Example1IntegrationTest.class, Example2IntegrationTest.class
|
Example1IntegrationTest.class, Example2IntegrationTest.class
|
||||||
};
|
};
|
||||||
|
@ -19,7 +19,7 @@ public class Spring5JUnit5ParallelIntegrationTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void givenTwoTestClasses_whenJUnitRunParallel_thenTheTestsExecutingLinear() {
|
void givenTwoTestClasses_whenJUnitRunParallel_thenTheTestsExecutingLinear() {
|
||||||
final Class<?>[] classes = {
|
final Class<?>[] classes = {
|
||||||
Example1IntegrationTest.class, Example2IntegrationTest.class
|
Example1IntegrationTest.class, Example2IntegrationTest.class
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
package com.baeldung.jupiter;
|
package com.baeldung.jupiter;
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
public class Spring5Java8NewFeaturesIntegrationTest {
|
class Spring5Java8NewFeaturesIntegrationTest {
|
||||||
|
|
||||||
@FunctionalInterface
|
@FunctionalInterface
|
||||||
public interface FunctionalInterfaceExample<Input, Result> {
|
public interface FunctionalInterfaceExample<Input, Result> {
|
||||||
|
@ -14,12 +16,10 @@ public class Spring5Java8NewFeaturesIntegrationTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
public class StringUtils {
|
public class StringUtils {
|
||||||
public FunctionalInterfaceExample<String, String>
|
FunctionalInterfaceExample<String, String>
|
||||||
functionLambdaString = s -> {
|
functionLambdaString = s -> Pattern.compile(" +").splitAsStream(s)
|
||||||
return Pattern.compile(" +").splitAsStream(s)
|
|
||||||
.map(word -> new StringBuilder(word).reverse())
|
.map(word -> new StringBuilder(word).reverse())
|
||||||
.collect(Collectors.joining(" "));
|
.collect(Collectors.joining(" "));
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -3,16 +3,8 @@ package com.baeldung.jupiter;
|
||||||
import com.baeldung.web.reactive.Task;
|
import com.baeldung.web.reactive.Task;
|
||||||
import org.junit.jupiter.api.AfterAll;
|
import org.junit.jupiter.api.AfterAll;
|
||||||
import org.junit.jupiter.api.BeforeAll;
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.springframework.http.HttpMethod;
|
|
||||||
import org.springframework.http.client.reactive.ReactorClientHttpConnector;
|
|
||||||
import org.springframework.http.server.reactive.HttpHandler;
|
import org.springframework.http.server.reactive.HttpHandler;
|
||||||
import org.springframework.http.server.reactive.ReactorHttpHandlerAdapter;
|
import org.springframework.http.server.reactive.ReactorHttpHandlerAdapter;
|
||||||
import org.springframework.web.reactive.function.BodyInserters;
|
|
||||||
import org.springframework.web.reactive.function.client.ClientRequest;
|
|
||||||
import org.springframework.web.reactive.function.client.ExchangeFunction;
|
|
||||||
import org.springframework.web.reactive.function.client.ExchangeFunctions;
|
|
||||||
import org.springframework.web.reactive.function.client.WebClient;
|
|
||||||
import org.springframework.web.reactive.function.server.RouterFunction;
|
import org.springframework.web.reactive.function.server.RouterFunction;
|
||||||
import org.springframework.web.reactive.function.server.RouterFunctions;
|
import org.springframework.web.reactive.function.server.RouterFunctions;
|
||||||
import org.springframework.web.reactive.function.server.ServerResponse;
|
import org.springframework.web.reactive.function.server.ServerResponse;
|
||||||
|
@ -21,10 +13,8 @@ import reactor.core.publisher.Mono;
|
||||||
import reactor.ipc.netty.NettyContext;
|
import reactor.ipc.netty.NettyContext;
|
||||||
import reactor.ipc.netty.http.server.HttpServer;
|
import reactor.ipc.netty.http.server.HttpServer;
|
||||||
|
|
||||||
import java.net.URI;
|
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
|
||||||
import static org.springframework.web.reactive.function.server.RequestPredicates.GET;
|
import static org.springframework.web.reactive.function.server.RequestPredicates.GET;
|
||||||
import static org.springframework.web.reactive.function.server.RequestPredicates.POST;
|
import static org.springframework.web.reactive.function.server.RequestPredicates.POST;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,101 @@
|
||||||
|
package com.baeldung.web;
|
||||||
|
|
||||||
|
import com.baeldung.Spring5Application;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
|
import org.springframework.test.web.reactive.server.WebTestClient;
|
||||||
|
|
||||||
|
@RunWith(SpringRunner.class)
|
||||||
|
@SpringBootTest(classes = Spring5Application.class)
|
||||||
|
public class PathPatternsUsingHandlerMethodIntegrationTest {
|
||||||
|
|
||||||
|
private static WebTestClient client;
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void setUp() {
|
||||||
|
client = WebTestClient.bindToController(new PathPatternController())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenHandlerMethod_whenMultipleURIVariablePattern_then200() {
|
||||||
|
|
||||||
|
client.get()
|
||||||
|
.uri("/spring5/ab/cd")
|
||||||
|
.exchange()
|
||||||
|
.expectStatus()
|
||||||
|
.is2xxSuccessful()
|
||||||
|
.expectBody()
|
||||||
|
.equals("/ab/cd");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenHandlerMethod_whenURLWithWildcardTakingZeroOrMoreChar_then200() {
|
||||||
|
|
||||||
|
client.get()
|
||||||
|
.uri("/spring5/userid")
|
||||||
|
.exchange()
|
||||||
|
.expectStatus()
|
||||||
|
.is2xxSuccessful()
|
||||||
|
.expectBody()
|
||||||
|
.equals("/spring5/*id");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenHandlerMethod_whenURLWithWildcardTakingExactlyOneChar_then200() {
|
||||||
|
|
||||||
|
client.get()
|
||||||
|
.uri("/string5")
|
||||||
|
.exchange()
|
||||||
|
.expectStatus()
|
||||||
|
.is2xxSuccessful()
|
||||||
|
.expectBody()
|
||||||
|
.equals("/s?ring5");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenHandlerMethod_whenURLWithWildcardTakingZeroOrMorePathSegments_then200() {
|
||||||
|
|
||||||
|
client.get()
|
||||||
|
.uri("/resources/baeldung")
|
||||||
|
.exchange()
|
||||||
|
.expectStatus()
|
||||||
|
.is2xxSuccessful()
|
||||||
|
.expectBody()
|
||||||
|
.equals("/resources/**");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenHandlerMethod_whenURLWithRegexInPathVariable_thenExpectedOutput() {
|
||||||
|
|
||||||
|
client.get()
|
||||||
|
.uri("/abc")
|
||||||
|
.exchange()
|
||||||
|
.expectStatus()
|
||||||
|
.is2xxSuccessful()
|
||||||
|
.expectBody()
|
||||||
|
.equals("abc");
|
||||||
|
|
||||||
|
client.get()
|
||||||
|
.uri("/123")
|
||||||
|
.exchange()
|
||||||
|
.expectStatus()
|
||||||
|
.is4xxClientError();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenHandlerMethod_whenURLWithMultiplePathVariablesInSameSegment_then200() {
|
||||||
|
|
||||||
|
client.get()
|
||||||
|
.uri("/baeldung_tutorial")
|
||||||
|
.exchange()
|
||||||
|
.expectStatus()
|
||||||
|
.is2xxSuccessful()
|
||||||
|
.expectBody()
|
||||||
|
.equals("Two variables are var1=baeldung and var2=tutorial");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -5,3 +5,4 @@
|
||||||
- [Constructor Dependency Injection in Spring](http://www.baeldung.com/constructor-injection-in-spring)
|
- [Constructor Dependency Injection in Spring](http://www.baeldung.com/constructor-injection-in-spring)
|
||||||
- [Constructor Injection in Spring with Lombok](http://www.baeldung.com/spring-injection-lombok)
|
- [Constructor Injection in Spring with Lombok](http://www.baeldung.com/spring-injection-lombok)
|
||||||
- [A Quick Guide to Spring @Value](http://www.baeldung.com/spring-value-annotation)
|
- [A Quick Guide to Spring @Value](http://www.baeldung.com/spring-value-annotation)
|
||||||
|
- [Spring YAML Configuration](http://www.baeldung.com/spring-yaml)
|
||||||
|
|
|
@ -58,6 +58,11 @@
|
||||||
<artifactId>lombok</artifactId>
|
<artifactId>lombok</artifactId>
|
||||||
<version>${lombok.version}</version>
|
<version>${lombok.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter</artifactId>
|
||||||
|
<version>1.5.2.RELEASE</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-test</artifactId>
|
<artifactId>spring-boot-test</artifactId>
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
* To change this license header, choose License Headers in Project Properties.
|
||||||
|
* To change this template file, choose Tools | Templates
|
||||||
|
* and open the template in the editor.
|
||||||
|
*/
|
||||||
|
package com.baeldung.yaml;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.CommandLineRunner;
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
public class MyApplication implements CommandLineRunner {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private YAMLConfig myConfig;
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication app = new SpringApplication(MyApplication.class);
|
||||||
|
app.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void run(String... args) throws Exception {
|
||||||
|
System.out.println("using environment:" + myConfig.getEnvironment());
|
||||||
|
System.out.println("name:" + myConfig.getName());
|
||||||
|
System.out.println("servers:" + myConfig.getServers());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
package com.baeldung.yaml;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@EnableConfigurationProperties
|
||||||
|
@ConfigurationProperties
|
||||||
|
public class YAMLConfig {
|
||||||
|
private String name;
|
||||||
|
private String environment;
|
||||||
|
private List<String> servers = new ArrayList<String>();
|
||||||
|
|
||||||
|
public List<String> getServers() {
|
||||||
|
return servers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setServers(List<String> servers) {
|
||||||
|
this.servers = servers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEnvironment() {
|
||||||
|
return environment;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEnvironment(String environment) {
|
||||||
|
this.environment = environment;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,2 +1,2 @@
|
||||||
someInitialValue=This is only sample value
|
spring.profiles.active=prod
|
||||||
anotherValue=Another configured value
|
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
spring:
|
||||||
|
profiles: test
|
||||||
|
name: test-YAML
|
||||||
|
environment: test
|
||||||
|
servers:
|
||||||
|
- www.abc.test.com
|
||||||
|
- www.xyz.test.com
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
spring:
|
||||||
|
profiles: prod
|
||||||
|
name: prod-YAML
|
||||||
|
environment: production
|
||||||
|
servers:
|
||||||
|
- www.abc.com
|
||||||
|
- www.xyz.com
|
|
@ -1,8 +1,7 @@
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>com.baeldung</groupId>
|
<artifactId>spring-jooq</artifactId>
|
||||||
<artifactId>sprin-jooq</artifactId>
|
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
|
|
|
@ -12,7 +12,7 @@ import io.restassured.authentication.FormAuthConfig;
|
||||||
import io.restassured.response.Response;
|
import io.restassured.response.Response;
|
||||||
import io.restassured.specification.RequestSpecification;
|
import io.restassured.specification.RequestSpecification;
|
||||||
|
|
||||||
public class LiveTest {
|
public class ApplicationLiveTest {
|
||||||
|
|
||||||
private final FormAuthConfig formAuthConfig = new FormAuthConfig("http://localhost:8082/spring-security-mvc-boot/login", "username", "password");
|
private final FormAuthConfig formAuthConfig = new FormAuthConfig("http://localhost:8082/spring-security-mvc-boot/login", "username", "password");
|
||||||
|
|
|
@ -25,18 +25,18 @@ import org.springframework.boot.test.context.SpringBootTest;
|
||||||
@WebAppConfiguration
|
@WebAppConfiguration
|
||||||
public class CustomUserDetailsServiceIntegrationTest {
|
public class CustomUserDetailsServiceIntegrationTest {
|
||||||
|
|
||||||
public static final String USERNAME = "user";
|
private static final String USERNAME = "user";
|
||||||
public static final String PASSWORD = "pass";
|
private static final String PASSWORD = "pass";
|
||||||
public static final String USERNAME2 = "user2";
|
private static final String USERNAME2 = "user2";
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
UserRepository myUserRepository;
|
private UserRepository myUserRepository;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
AuthenticationProvider authenticationProvider;
|
private AuthenticationProvider authenticationProvider;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
PasswordEncoder passwordEncoder;
|
private PasswordEncoder passwordEncoder;
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
package org.baeldung.web;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
|
import org.baeldung.multipleauthproviders.MultipleAuthProvidersApplication;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||||
|
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
|
|
||||||
|
@RunWith(SpringRunner.class)
|
||||||
|
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, classes = MultipleAuthProvidersApplication.class)
|
||||||
|
public class MultipleAuthProvidersApplicationIntegrationTest {
|
||||||
|
@Autowired
|
||||||
|
private TestRestTemplate restTemplate;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenMemUsers_whenGetPingWithValidUser_thenOk() {
|
||||||
|
ResponseEntity<String> result = makeRestCallToGetPing("memuser", "pass");
|
||||||
|
|
||||||
|
assertThat(result.getStatusCodeValue()).isEqualTo(200);
|
||||||
|
assertThat(result.getBody()).isEqualTo("OK");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenExternalUsers_whenGetPingWithValidUser_thenOK() {
|
||||||
|
ResponseEntity<String> result = makeRestCallToGetPing("externaluser", "pass");
|
||||||
|
|
||||||
|
assertThat(result.getStatusCodeValue()).isEqualTo(200);
|
||||||
|
assertThat(result.getBody()).isEqualTo("OK");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenAuthProviders_whenGetPingWithNoCred_then401() {
|
||||||
|
ResponseEntity<String> result = makeRestCallToGetPing();
|
||||||
|
|
||||||
|
assertThat(result.getStatusCodeValue()).isEqualTo(401);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenAuthProviders_whenGetPingWithBadCred_then401() {
|
||||||
|
ResponseEntity<String> result = makeRestCallToGetPing("user", "bad_password");
|
||||||
|
|
||||||
|
assertThat(result.getStatusCodeValue()).isEqualTo(401);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ResponseEntity<String> makeRestCallToGetPing(String username, String password) {
|
||||||
|
return restTemplate.withBasicAuth(username, password)
|
||||||
|
.getForEntity("/api/ping", String.class, Collections.emptyMap());
|
||||||
|
}
|
||||||
|
|
||||||
|
private ResponseEntity<String> makeRestCallToGetPing() {
|
||||||
|
return restTemplate.getForEntity("/api/ping", String.class, Collections.emptyMap());
|
||||||
|
}
|
||||||
|
}
|
|
@ -21,6 +21,7 @@ import static org.springframework.security.test.web.servlet.request.SecurityMock
|
||||||
@WebAppConfiguration
|
@WebAppConfiguration
|
||||||
@SpringBootTest(classes = MultipleEntryPointsApplication.class)
|
@SpringBootTest(classes = MultipleEntryPointsApplication.class)
|
||||||
public class MultipleEntryPointsIntegrationTest {
|
public class MultipleEntryPointsIntegrationTest {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private WebApplicationContext wac;
|
private WebApplicationContext wac;
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,7 @@
|
||||||
package com.baeldung.vertxspring.repository;
|
package com.baeldung.vertxspring.repository;
|
||||||
|
|
||||||
import org.springframework.data.repository.CrudRepository;
|
|
||||||
import org.springframework.stereotype.Repository;
|
|
||||||
|
|
||||||
import com.baeldung.vertxspring.entity.Article;
|
import com.baeldung.vertxspring.entity.Article;
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
|
||||||
@Repository
|
public interface ArticleRepository extends JpaRepository<Article, Long> {
|
||||||
public interface ArticleRepository extends CrudRepository<Article, Long> {
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,25 +1,20 @@
|
||||||
package com.baeldung.vertxspring.service;
|
package com.baeldung.vertxspring.service;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
|
|
||||||
import com.baeldung.vertxspring.entity.Article;
|
import com.baeldung.vertxspring.entity.Article;
|
||||||
import com.baeldung.vertxspring.repository.ArticleRepository;
|
import com.baeldung.vertxspring.repository.ArticleRepository;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class ArticleService {
|
public class ArticleService {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
ArticleRepository articleRepository;
|
private ArticleRepository articleRepository;
|
||||||
|
|
||||||
public List<Article> getAllArticle() {
|
public List<Article> getAllArticle() {
|
||||||
List<Article> articles = new ArrayList<>();
|
return articleRepository.findAll();
|
||||||
articleRepository.findAll()
|
|
||||||
.forEach(articles::add);
|
|
||||||
return articles;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue