Убрал функцию сохранения позиции пользователя в сценарии. Теперь этот функционал должна реализовывать библиотека-клиент.
This commit is contained in:
parent
f03bf1fc05
commit
deb53d600e
2
pom.xml
2
pom.xml
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
<groupId>dev.struchkov</groupId>
|
<groupId>dev.struchkov</groupId>
|
||||||
<artifactId>autoresponder</artifactId>
|
<artifactId>autoresponder</artifactId>
|
||||||
<version>2.0.1</version>
|
<version>3.0.0</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<name>Abstract Autoresponder</name>
|
<name>Abstract Autoresponder</name>
|
||||||
|
@ -1,159 +0,0 @@
|
|||||||
package dev.struchkov.autoresponder;
|
|
||||||
|
|
||||||
import dev.struchkov.autoresponder.compare.UnitPriorityComparator;
|
|
||||||
import dev.struchkov.autoresponder.entity.Unit;
|
|
||||||
import dev.struchkov.autoresponder.entity.UnitPointer;
|
|
||||||
import dev.struchkov.autoresponder.service.UnitPointerService;
|
|
||||||
import dev.struchkov.autoresponder.util.Message;
|
|
||||||
import dev.struchkov.autoresponder.util.Parser;
|
|
||||||
import dev.struchkov.haiti.utils.Inspector;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import static dev.struchkov.haiti.utils.Inspector.isEmpty;
|
|
||||||
import static dev.struchkov.haiti.utils.Inspector.isNotEmpty;
|
|
||||||
import static dev.struchkov.haiti.utils.Inspector.isNotNull;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Реализуют основную логику автоответчика.
|
|
||||||
*
|
|
||||||
* @author upagge [07/07/2019]
|
|
||||||
*/
|
|
||||||
public class AutoResponder<U extends Unit<U>> {
|
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(AutoResponder.class);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Компоратор для сортировки Unit-ов
|
|
||||||
*/
|
|
||||||
private static final UnitPriorityComparator UNIT_PRIORITY_COMPARATOR = new UnitPriorityComparator();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Начальные юниты, первый запрос приходит на них
|
|
||||||
*/
|
|
||||||
private final Set<U> startUnits;
|
|
||||||
|
|
||||||
private final UnitPointerService<U> unitPointerService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Дефолтный юнит, отправляется если ни один Unit не подошел
|
|
||||||
*/
|
|
||||||
private U defaultUnit;
|
|
||||||
|
|
||||||
public AutoResponder(UnitPointerService<U> unitPointerService, Set<U> startUnits) {
|
|
||||||
this.startUnits = startUnits;
|
|
||||||
this.unitPointerService = unitPointerService;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Принимает текстовый запрос пользователя и отдает юнит, который соответствует запросу
|
|
||||||
*
|
|
||||||
* @param entityId Идентификатор клиента
|
|
||||||
* @param message Запрос пользователя - текстовое сообщение
|
|
||||||
* @return {@link Unit}, который отвечает за данные для обработки данного запроса
|
|
||||||
*/
|
|
||||||
public Optional<U> answer(Long entityId, String message) {
|
|
||||||
isNotNull(entityId, message);
|
|
||||||
Optional<UnitPointer<U>> unitPointer = unitPointerService.getByEntityId(entityId);
|
|
||||||
final Optional<U> answer = nextUnit(
|
|
||||||
unitPointer.isPresent()
|
|
||||||
&& unitPointer.get().getUnit().getNextUnits() != null
|
|
||||||
&& !unitPointer.get().getUnit().getNextUnits().isEmpty()
|
|
||||||
? unitPointer.get().getUnit().getNextUnits()
|
|
||||||
: startUnits,
|
|
||||||
message
|
|
||||||
);
|
|
||||||
if (answer.isPresent()) {
|
|
||||||
final U unitAnswer = answer.get();
|
|
||||||
final Set<U> nextUnits = unitAnswer.getNextUnits();
|
|
||||||
if (isEmpty(nextUnits)) {
|
|
||||||
unitPointerService.removeByEntityId(entityId);
|
|
||||||
} else {
|
|
||||||
unitPointerService.save(new UnitPointer<>(entityId, unitAnswer));
|
|
||||||
}
|
|
||||||
return answer;
|
|
||||||
} else {
|
|
||||||
return Optional.ofNullable(defaultUnit);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Выбирает, какой {@link Unit} будет отдан для обработки
|
|
||||||
*
|
|
||||||
* @param nextUnits Множество следующих Unit-ов
|
|
||||||
* @param message Запрос пользователя - текстовое сообщение
|
|
||||||
* @return Юнит, который нуждается в обработке в соответствии с запросом пользователя
|
|
||||||
*/
|
|
||||||
private Optional<U> nextUnit(Set<U> nextUnits, String message) {
|
|
||||||
isNotNull(nextUnits, message);
|
|
||||||
final Set<U> searchUnit = new HashSet<>();
|
|
||||||
|
|
||||||
if (isNotEmpty(nextUnits)) {
|
|
||||||
for (U unit : nextUnits) {
|
|
||||||
if (unit.getPhrase() != null
|
|
||||||
&& !unit.getPhrase().isEmpty()
|
|
||||||
&& unit.getPhrase().equalsIgnoreCase(message)) {
|
|
||||||
searchUnit.add(unit);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (unit.getPattern() != null && patternReg(unit, message)) {
|
|
||||||
searchUnit.add(unit);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (percentageMatch(unit, Parser.parse(message)) >= unit.getMatchThreshold()) {
|
|
||||||
searchUnit.add(unit);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isEmpty(searchUnit)) {
|
|
||||||
for (U nextUnit : nextUnits) {
|
|
||||||
if ((nextUnit.getPattern() == null && (nextUnit.getKeyWords() == null || nextUnit.getKeyWords().isEmpty()))) {
|
|
||||||
searchUnit.add(nextUnit);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return searchUnit.stream().max(UNIT_PRIORITY_COMPARATOR);
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean patternReg(U unit, String message) {
|
|
||||||
isNotNull(unit);
|
|
||||||
return message.matches(unit.getPattern().pattern());
|
|
||||||
}
|
|
||||||
|
|
||||||
private Double percentageMatch(U unit, Set<String> words) {
|
|
||||||
final Set<String> keyWords = unit.getKeyWords();
|
|
||||||
if (keyWords != null && !keyWords.isEmpty()) {
|
|
||||||
final Set<String> temp = new HashSet<>(keyWords);
|
|
||||||
temp.retainAll(words);
|
|
||||||
log.trace(Message.UNIT_KEYWORDS, keyWords, keyWords.size());
|
|
||||||
log.trace(Message.USER_MESSAGE_KEYWORDS, words);
|
|
||||||
log.trace(Message.INTERSECTION, temp, temp.size());
|
|
||||||
log.trace(Message.CROSSING_PERCENTAGE, (double) temp.size() / (double) keyWords.size() * 100.0, unit.getMatchThreshold());
|
|
||||||
return (double) temp.size() / (double) keyWords.size() * 100.0;
|
|
||||||
} else {
|
|
||||||
return 0.0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public UnitPointerService<U> getUnitPointerService() {
|
|
||||||
return unitPointerService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Set<U> getStartUnits() {
|
|
||||||
return startUnits;
|
|
||||||
}
|
|
||||||
|
|
||||||
public U getDefaultUnit() {
|
|
||||||
return defaultUnit;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDefaultUnit(U defaultUnit) {
|
|
||||||
this.defaultUnit = defaultUnit;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
100
src/main/java/dev/struchkov/autoresponder/Responder.java
Normal file
100
src/main/java/dev/struchkov/autoresponder/Responder.java
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
package dev.struchkov.autoresponder;
|
||||||
|
|
||||||
|
import dev.struchkov.autoresponder.compare.UnitPriorityComparator;
|
||||||
|
import dev.struchkov.autoresponder.entity.Unit;
|
||||||
|
import dev.struchkov.autoresponder.util.Message;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import static dev.struchkov.autoresponder.util.Parser.splitWords;
|
||||||
|
import static dev.struchkov.haiti.utils.Exceptions.utilityClass;
|
||||||
|
import static dev.struchkov.haiti.utils.Inspector.isNotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Реализуют основную логику автоответчика.
|
||||||
|
*
|
||||||
|
* @author upagge [07/07/2019]
|
||||||
|
*/
|
||||||
|
public final class Responder {
|
||||||
|
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(Responder.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Компоратор для сортировки Unit-ов
|
||||||
|
*/
|
||||||
|
private static final UnitPriorityComparator UNIT_PRIORITY_COMPARATOR = new UnitPriorityComparator();
|
||||||
|
|
||||||
|
private Responder() {
|
||||||
|
utilityClass();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Выбирает, какой {@link Unit} будет отдан для обработки
|
||||||
|
*
|
||||||
|
* @param nextUnits Множество следующих Unit-ов
|
||||||
|
* @param message Запрос пользователя - текстовое сообщение
|
||||||
|
* @return Юнит, который нуждается в обработке в соответствии с запросом пользователя
|
||||||
|
*/
|
||||||
|
public static <U extends Unit<U>> Optional<U> nextUnit(String message, Collection<U> nextUnits) {
|
||||||
|
isNotNull(nextUnits, message);
|
||||||
|
final Set<U> searchUnit = new HashSet<>();
|
||||||
|
|
||||||
|
if (nextUnits != null) {
|
||||||
|
for (U unit : nextUnits) {
|
||||||
|
final String unitPhrase = unit.getPhrase();
|
||||||
|
if (
|
||||||
|
unitPhrase != null
|
||||||
|
&& !unitPhrase.isEmpty()
|
||||||
|
&& unitPhrase.equalsIgnoreCase(message)
|
||||||
|
) {
|
||||||
|
searchUnit.add(unit);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (unit.getPattern() != null && patternReg(unit.getPattern(), message)) {
|
||||||
|
searchUnit.add(unit);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (percentageMatch(unit, splitWords(message)) >= unit.getMatchThreshold()) {
|
||||||
|
searchUnit.add(unit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (searchUnit.isEmpty()) {
|
||||||
|
for (U nextUnit : nextUnits) {
|
||||||
|
if ((nextUnit.getPattern() == null && (nextUnit.getKeyWords() == null || nextUnit.getKeyWords().isEmpty()))) {
|
||||||
|
searchUnit.add(nextUnit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return searchUnit.stream().max(UNIT_PRIORITY_COMPARATOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean patternReg(Pattern pattern, String message) {
|
||||||
|
isNotNull(pattern);
|
||||||
|
return message.matches(pattern.pattern());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static <U extends Unit<U>> Double percentageMatch(U unit, Set<String> words) {
|
||||||
|
final Set<String> keyWords = unit.getKeyWords();
|
||||||
|
if (keyWords != null && !keyWords.isEmpty()) {
|
||||||
|
final Set<String> temp = new HashSet<>(keyWords);
|
||||||
|
temp.retainAll(words);
|
||||||
|
log.trace(Message.UNIT_KEYWORDS, keyWords, keyWords.size());
|
||||||
|
log.trace(Message.USER_MESSAGE_KEYWORDS, words);
|
||||||
|
log.trace(Message.INTERSECTION, temp, temp.size());
|
||||||
|
log.trace(Message.CROSSING_PERCENTAGE, (double) temp.size() / (double) keyWords.size() * 100.0, unit.getMatchThreshold());
|
||||||
|
return (double) temp.size() / (double) keyWords.size() * 100.0;
|
||||||
|
} else {
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,56 +0,0 @@
|
|||||||
package dev.struchkov.autoresponder.entity;
|
|
||||||
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Сущность для сохранения позиции пользователя в сценарии, состоящем из связного списка элементов {@link Unit}.
|
|
||||||
*
|
|
||||||
* @author upagge [07/07/2019]
|
|
||||||
*/
|
|
||||||
public class UnitPointer<U extends Unit<U>> {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Идентификатор пользователя.
|
|
||||||
*/
|
|
||||||
private Long entityId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Юнит, который был обработан.
|
|
||||||
*/
|
|
||||||
private U unit;
|
|
||||||
|
|
||||||
public UnitPointer(Long entityId, U unit) {
|
|
||||||
this.entityId = entityId;
|
|
||||||
this.unit = unit;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Long getEntityId() {
|
|
||||||
return entityId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setEntityId(Long entityId) {
|
|
||||||
this.entityId = entityId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public U getUnit() {
|
|
||||||
return unit;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUnit(U unit) {
|
|
||||||
this.unit = unit;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (this == o) return true;
|
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
|
||||||
UnitPointer<?> that = (UnitPointer<?>) o;
|
|
||||||
return Objects.equals(entityId, that.entityId);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return Objects.hash(entityId);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,26 +0,0 @@
|
|||||||
package dev.struchkov.autoresponder.repository;
|
|
||||||
|
|
||||||
import dev.struchkov.autoresponder.entity.Unit;
|
|
||||||
import dev.struchkov.autoresponder.entity.UnitPointer;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Интегрфейс для работы с хранилищем сущности {@link UnitPointer}.
|
|
||||||
*
|
|
||||||
* @author upagge [07/07/2019]
|
|
||||||
*/
|
|
||||||
public interface UnitPointerRepository<U extends Unit<U>> {
|
|
||||||
|
|
||||||
UnitPointer<U> save(@NotNull UnitPointer<U> unitPointer);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param entityId Идентификатор пользователя
|
|
||||||
* @return Объект с последним обработанным {@link Unit} для пользователя
|
|
||||||
*/
|
|
||||||
Optional<UnitPointer<U>> findByEntityId(Long entityId);
|
|
||||||
|
|
||||||
void removeByEntityId(Long entityId);
|
|
||||||
|
|
||||||
}
|
|
@ -1,41 +0,0 @@
|
|||||||
package dev.struchkov.autoresponder.repository;
|
|
||||||
|
|
||||||
import dev.struchkov.autoresponder.entity.Unit;
|
|
||||||
import dev.struchkov.autoresponder.entity.UnitPointer;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
import static dev.struchkov.haiti.utils.Inspector.isNotNull;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Реализация хранилища для {@link UnitPointer} на основе Map.
|
|
||||||
*
|
|
||||||
* @author upagge [07/07/2019]
|
|
||||||
*/
|
|
||||||
public class UnitPointerRepositoryMap<U extends Unit<U>> implements UnitPointerRepository<U> {
|
|
||||||
|
|
||||||
private final Map<Long, UnitPointer<U>> unitPointerMap = new HashMap<>();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public UnitPointer<U> save(@NotNull UnitPointer<U> unitPointer) {
|
|
||||||
// isNotNull(unitPointer);
|
|
||||||
unitPointerMap.put(unitPointer.getEntityId(), unitPointer);
|
|
||||||
return unitPointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Optional<UnitPointer<U>> findByEntityId(Long entityId) {
|
|
||||||
isNotNull(entityId);
|
|
||||||
return Optional.ofNullable(unitPointerMap.get(entityId));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void removeByEntityId(Long entityId) {
|
|
||||||
isNotNull(entityId);
|
|
||||||
unitPointerMap.remove(entityId);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,22 +0,0 @@
|
|||||||
package dev.struchkov.autoresponder.service;
|
|
||||||
|
|
||||||
import dev.struchkov.autoresponder.entity.Unit;
|
|
||||||
import dev.struchkov.autoresponder.entity.UnitPointer;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Сервис для взаимодействия с сущностью {@link UnitPointer}.
|
|
||||||
*
|
|
||||||
* @author upagge [07/07/2019]
|
|
||||||
*/
|
|
||||||
public interface UnitPointerService<U extends Unit<U>> {
|
|
||||||
|
|
||||||
void save(@NotNull UnitPointer<U> unitPointer);
|
|
||||||
|
|
||||||
Optional<UnitPointer<U>> getByEntityId(@NotNull Long entityId);
|
|
||||||
|
|
||||||
void removeByEntityId(@NotNull Long entityId);
|
|
||||||
|
|
||||||
}
|
|
@ -1,43 +0,0 @@
|
|||||||
package dev.struchkov.autoresponder.service;
|
|
||||||
|
|
||||||
import dev.struchkov.autoresponder.entity.Unit;
|
|
||||||
import dev.struchkov.autoresponder.entity.UnitPointer;
|
|
||||||
import dev.struchkov.autoresponder.repository.UnitPointerRepository;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
import static dev.struchkov.haiti.utils.Inspector.isNotNull;
|
|
||||||
|
|
||||||
public class UnitPointerServiceImpl<U extends Unit<U>> implements UnitPointerService<U> {
|
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(UnitPointerServiceImpl.class);
|
|
||||||
|
|
||||||
private final UnitPointerRepository<U> unitPointerRepository;
|
|
||||||
|
|
||||||
public UnitPointerServiceImpl(UnitPointerRepository<U> unitPointerRepository) {
|
|
||||||
this.unitPointerRepository = unitPointerRepository;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Optional<UnitPointer<U>> getByEntityId(@NotNull Long entityId) {
|
|
||||||
isNotNull(entityId);
|
|
||||||
return unitPointerRepository.findByEntityId(entityId);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void removeByEntityId(@NotNull Long entityId) {
|
|
||||||
isNotNull(entityId);
|
|
||||||
unitPointerRepository.removeByEntityId(entityId);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void save(@NotNull UnitPointer<U> unitPointer) {
|
|
||||||
isNotNull(unitPointer);
|
|
||||||
unitPointerRepository.save(unitPointer);
|
|
||||||
log.trace("Пользователь отправлен в репозиторий");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -30,7 +30,7 @@ public class Parser {
|
|||||||
* @param text Строка
|
* @param text Строка
|
||||||
* @return Множество слов
|
* @return Множество слов
|
||||||
*/
|
*/
|
||||||
public static Set<String> parse(String text) {
|
public static Set<String> splitWords(String text) {
|
||||||
final String[] split = text.split("\\P{L}+");
|
final String[] split = text.split("\\P{L}+");
|
||||||
final Set<String> words = Arrays.stream(split).map(String::toLowerCase).collect(Collectors.toSet());
|
final Set<String> words = Arrays.stream(split).map(String::toLowerCase).collect(Collectors.toSet());
|
||||||
words.removeAll(pretexts);
|
words.removeAll(pretexts);
|
||||||
|
@ -1,39 +0,0 @@
|
|||||||
package dev.struchkov.autoresponder.util;
|
|
||||||
|
|
||||||
import dev.struchkov.autoresponder.entity.Unit;
|
|
||||||
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import static dev.struchkov.haiti.utils.Exceptions.utilityClass;
|
|
||||||
import static dev.struchkov.haiti.utils.Inspector.isNotEmpty;
|
|
||||||
import static dev.struchkov.haiti.utils.Inspector.isNotNull;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Утилитарный класс с полезными методами для работы с юнитами.
|
|
||||||
*/
|
|
||||||
public class Units {
|
|
||||||
|
|
||||||
private Units() {
|
|
||||||
utilityClass();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Позволяет связать два разных юнита. Используется, чтобы побороть циклические зависимости в различных фреймворках.
|
|
||||||
*
|
|
||||||
* @param first К этому юниту будет присоединен юнит second.
|
|
||||||
* @param second Этот юнит присоединяется после first.
|
|
||||||
*/
|
|
||||||
public static void link(Unit first, Unit second) {
|
|
||||||
isNotNull(first, second);
|
|
||||||
final Set<Unit> nextUnits = first.getNextUnits();
|
|
||||||
if (nextUnits != null) {
|
|
||||||
nextUnits.add(second);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void link(Unit first, Unit... other) {
|
|
||||||
isNotNull(first);
|
|
||||||
isNotEmpty(other);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,143 +1,143 @@
|
|||||||
package dev.struchkov.autoresponder;
|
//package dev.struchkov.autoresponder;
|
||||||
|
//
|
||||||
import dev.struchkov.autoresponder.repository.UnitPointerRepositoryMap;
|
//import dev.struchkov.autoresponder.repository.UnitPointerRepositoryMap;
|
||||||
import dev.struchkov.autoresponder.service.UnitPointerServiceImpl;
|
//import dev.struchkov.autoresponder.service.UnitPointerServiceImpl;
|
||||||
import dev.struchkov.autoresponder.test.TestUnit;
|
//import dev.struchkov.autoresponder.test.TestUnit;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
//import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
//import org.junit.jupiter.api.Test;
|
||||||
|
//
|
||||||
import java.util.HashSet;
|
//import java.util.HashSet;
|
||||||
import java.util.Optional;
|
//import java.util.Optional;
|
||||||
import java.util.Set;
|
//import java.util.Set;
|
||||||
import java.util.regex.Pattern;
|
//import java.util.regex.Pattern;
|
||||||
import java.util.stream.Collectors;
|
//import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
//import java.util.stream.Stream;
|
||||||
|
//
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
//import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
//
|
||||||
class AutoResponderTest {
|
//class AutoResponderTest {
|
||||||
|
//
|
||||||
private AutoResponder<TestUnit> autoresponder;
|
// private AutoResponder<TestUnit> autoresponder;
|
||||||
|
//
|
||||||
@BeforeEach
|
// @BeforeEach
|
||||||
public void setUp() {
|
// public void setUp() {
|
||||||
final TestUnit dela = TestUnit.builder()
|
// final TestUnit dela = TestUnit.builder()
|
||||||
.keyWord("дела")
|
// .keyWord("дела")
|
||||||
.keyWord("делишки")
|
// .keyWord("делишки")
|
||||||
.message("хорошо")
|
// .message("хорошо")
|
||||||
.build();
|
// .build();
|
||||||
|
//
|
||||||
final TestUnit delaTop = TestUnit.builder()
|
// final TestUnit delaTop = TestUnit.builder()
|
||||||
.priority(100)
|
// .priority(100)
|
||||||
.keyWord("делишки")
|
// .keyWord("делишки")
|
||||||
.message("отлично")
|
// .message("отлично")
|
||||||
.build();
|
// .build();
|
||||||
|
//
|
||||||
final TestUnit hello = TestUnit.builder()
|
// final TestUnit hello = TestUnit.builder()
|
||||||
.keyWord("привет")
|
// .keyWord("привет")
|
||||||
.message("тест")
|
// .message("тест")
|
||||||
.nextUnit(dela)
|
// .nextUnit(dela)
|
||||||
.nextUnit(delaTop)
|
// .nextUnit(delaTop)
|
||||||
.build();
|
// .build();
|
||||||
|
//
|
||||||
|
//
|
||||||
final TestUnit number = TestUnit.builder()
|
// final TestUnit number = TestUnit.builder()
|
||||||
.keyWord("89101234567")
|
// .keyWord("89101234567")
|
||||||
.message("ответ")
|
// .message("ответ")
|
||||||
.build();
|
// .build();
|
||||||
|
//
|
||||||
final TestUnit regExp = TestUnit.builder()
|
// final TestUnit regExp = TestUnit.builder()
|
||||||
.pattern(Pattern.compile("^((8|\\+7)[\\- ]?)?(\\(?\\d{3}\\)?[\\- ]?)?[\\d\\- ]{7,10}$"))
|
// .pattern(Pattern.compile("^((8|\\+7)[\\- ]?)?(\\(?\\d{3}\\)?[\\- ]?)?[\\d\\- ]{7,10}$"))
|
||||||
.message("регулярка")
|
// .message("регулярка")
|
||||||
.build();
|
// .build();
|
||||||
dela.setNextUnits(Stream.of(regExp, number).collect(Collectors.toSet()));
|
// dela.setNextUnits(Stream.of(regExp, number).collect(Collectors.toSet()));
|
||||||
|
//
|
||||||
final Set<String> strings = Stream.of("витамин", "мультифрукт", "арбуз", "параметр").collect(Collectors.toSet());
|
// final Set<String> strings = Stream.of("витамин", "мультифрукт", "арбуз", "параметр").collect(Collectors.toSet());
|
||||||
|
//
|
||||||
final TestUnit unreal = TestUnit.builder()
|
// final TestUnit unreal = TestUnit.builder()
|
||||||
.keyWords(strings)
|
// .keyWords(strings)
|
||||||
.message("победа")
|
// .message("победа")
|
||||||
.matchThreshold(100)
|
// .matchThreshold(100)
|
||||||
.build();
|
// .build();
|
||||||
|
//
|
||||||
final Set<TestUnit> testUnits = new HashSet<>();
|
// final Set<TestUnit> testUnits = new HashSet<>();
|
||||||
testUnits.add(hello);
|
// testUnits.add(hello);
|
||||||
testUnits.add(regExp);
|
// testUnits.add(regExp);
|
||||||
testUnits.add(unreal);
|
// testUnits.add(unreal);
|
||||||
|
//
|
||||||
final UnitPointerRepositoryMap<TestUnit> unitPointerRepository = new UnitPointerRepositoryMap<>();
|
// final UnitPointerRepositoryMap<TestUnit> unitPointerRepository = new UnitPointerRepositoryMap<>();
|
||||||
final UnitPointerServiceImpl<TestUnit> unitPointerService = new UnitPointerServiceImpl<>(unitPointerRepository);
|
// final UnitPointerServiceImpl<TestUnit> unitPointerService = new UnitPointerServiceImpl<>(unitPointerRepository);
|
||||||
autoresponder = new AutoResponder<>(unitPointerService, testUnits);
|
// autoresponder = new AutoResponder<>(unitPointerService, testUnits);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Test
|
// @Test
|
||||||
void simpleAnswer() {
|
// void simpleAnswer() {
|
||||||
final String message = autoresponder.answer(1L, "привет это тестирвоание функциональности").orElseThrow(NullPointerException::new).getMessage();
|
// final String message = autoresponder.answer(1L, "привет это тестирвоание функциональности").orElseThrow(NullPointerException::new).getMessage();
|
||||||
assertEquals("тест", message);
|
// assertEquals("тест", message);
|
||||||
final String message1 = autoresponder.answer(2L, "привет, еще одно тестирование").orElseThrow(NullPointerException::new).getMessage();
|
// final String message1 = autoresponder.answer(2L, "привет, еще одно тестирование").orElseThrow(NullPointerException::new).getMessage();
|
||||||
assertEquals("тест", message1);
|
// assertEquals("тест", message1);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Test
|
// @Test
|
||||||
void defaultAnswer() {
|
// void defaultAnswer() {
|
||||||
final TestUnit defaultUnit = TestUnit.builder().message("не знаю").build();
|
// final TestUnit defaultUnit = TestUnit.builder().message("не знаю").build();
|
||||||
autoresponder.setDefaultUnit(defaultUnit);
|
// autoresponder.setDefaultUnit(defaultUnit);
|
||||||
|
//
|
||||||
assertEquals("не знаю", autoresponder.answer(2L, "пока").orElseThrow(NullPointerException::new).getMessage());
|
// assertEquals("не знаю", autoresponder.answer(2L, "пока").orElseThrow(NullPointerException::new).getMessage());
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Test
|
// @Test
|
||||||
void notDefaultAnswer() {
|
// void notDefaultAnswer() {
|
||||||
assertEquals(Optional.empty(), autoresponder.answer(2L, "пока"));
|
// assertEquals(Optional.empty(), autoresponder.answer(2L, "пока"));
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Test
|
// @Test
|
||||||
void regExpAnswer() {
|
// void regExpAnswer() {
|
||||||
final String message = autoresponder.answer(1L, "79101234567").orElseThrow(NullPointerException::new).getMessage();
|
// final String message = autoresponder.answer(1L, "79101234567").orElseThrow(NullPointerException::new).getMessage();
|
||||||
assertEquals("регулярка", message);
|
// assertEquals("регулярка", message);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Test
|
// @Test
|
||||||
void priorityAnswer() {
|
// void priorityAnswer() {
|
||||||
autoresponder.answer(1L, "привет");
|
// autoresponder.answer(1L, "привет");
|
||||||
autoresponder.answer(2L, "привет");
|
// autoresponder.answer(2L, "привет");
|
||||||
final String message = autoresponder.answer(1L, "как твои делишки").orElseThrow(NullPointerException::new).getMessage();
|
// final String message = autoresponder.answer(1L, "как твои делишки").orElseThrow(NullPointerException::new).getMessage();
|
||||||
assertEquals("отлично", message);
|
// assertEquals("отлично", message);
|
||||||
final String message1 = autoresponder.answer(2L, "твои дела все еще хорошо?").orElseThrow(NullPointerException::new).getMessage();
|
// final String message1 = autoresponder.answer(2L, "твои дела все еще хорошо?").orElseThrow(NullPointerException::new).getMessage();
|
||||||
assertEquals("хорошо", message1);
|
// assertEquals("хорошо", message1);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Test
|
// @Test
|
||||||
void showRegExpVsKeyWords() {
|
// void showRegExpVsKeyWords() {
|
||||||
autoresponder.answer(1L, "привет");
|
// autoresponder.answer(1L, "привет");
|
||||||
autoresponder.answer(1L, "дела");
|
// autoresponder.answer(1L, "дела");
|
||||||
assertEquals("регулярка", autoresponder.answer(1L, "89101234567").orElseThrow(NullPointerException::new).getMessage());
|
// assertEquals("регулярка", autoresponder.answer(1L, "89101234567").orElseThrow(NullPointerException::new).getMessage());
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Test
|
// @Test
|
||||||
void matchThreshold() {
|
// void matchThreshold() {
|
||||||
autoresponder.answer(1L, "витамин я сьем, и арбуз получу");
|
// autoresponder.answer(1L, "витамин я сьем, и арбуз получу");
|
||||||
final String message = "параметр себе задам: покушать витамин и арбуз, а вместе все это мультифрукт";
|
// final String message = "параметр себе задам: покушать витамин и арбуз, а вместе все это мультифрукт";
|
||||||
final String answer = autoresponder.answer(1L, message).orElseThrow(NullPointerException::new).getMessage();
|
// final String answer = autoresponder.answer(1L, message).orElseThrow(NullPointerException::new).getMessage();
|
||||||
assertEquals("победа", answer);
|
// assertEquals("победа", answer);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Test
|
// @Test
|
||||||
void generalAnswer() {
|
// void generalAnswer() {
|
||||||
TestUnit defaultUnit = TestUnit.builder().message("не знаю").build();
|
// TestUnit defaultUnit = TestUnit.builder().message("не знаю").build();
|
||||||
autoresponder.setDefaultUnit(defaultUnit);
|
// autoresponder.setDefaultUnit(defaultUnit);
|
||||||
final String answer = autoresponder.answer(1L, "привет это тестирование функциональности").orElseThrow(NullPointerException::new).getMessage();
|
// final String answer = autoresponder.answer(1L, "привет это тестирование функциональности").orElseThrow(NullPointerException::new).getMessage();
|
||||||
assertEquals("тест", answer);
|
// assertEquals("тест", answer);
|
||||||
assertEquals("хорошо", autoresponder.answer(1L, "как твои дела").orElseThrow(NullPointerException::new).getMessage());
|
// assertEquals("хорошо", autoresponder.answer(1L, "как твои дела").orElseThrow(NullPointerException::new).getMessage());
|
||||||
final String answer2 = autoresponder.answer(2L, "привет это тестирование функциональности").orElseThrow(NullPointerException::new).getMessage();
|
// final String answer2 = autoresponder.answer(2L, "привет это тестирование функциональности").orElseThrow(NullPointerException::new).getMessage();
|
||||||
assertEquals("тест", answer2);
|
// assertEquals("тест", answer2);
|
||||||
assertEquals("не знаю", autoresponder.answer(1L, "нет").orElseThrow(NullPointerException::new).getMessage());
|
// assertEquals("не знаю", autoresponder.answer(1L, "нет").orElseThrow(NullPointerException::new).getMessage());
|
||||||
final String message = "параметр себе задам: покушать витамин и арбуз, а вместе все это мультифрукт";
|
// final String message = "параметр себе задам: покушать витамин и арбуз, а вместе все это мультифрукт";
|
||||||
assertEquals("победа", autoresponder.answer(3L, message).orElseThrow(NullPointerException::new).getMessage());
|
// assertEquals("победа", autoresponder.answer(3L, message).orElseThrow(NullPointerException::new).getMessage());
|
||||||
assertEquals("регулярка", autoresponder.answer(1L, "8912345678").orElseThrow(NullPointerException::new).getMessage());
|
// assertEquals("регулярка", autoresponder.answer(1L, "8912345678").orElseThrow(NullPointerException::new).getMessage());
|
||||||
final String answer3 = autoresponder.answer(1L, "привет это тестирование функциональности").orElseThrow(NullPointerException::new).getMessage();
|
// final String answer3 = autoresponder.answer(1L, "привет это тестирование функциональности").orElseThrow(NullPointerException::new).getMessage();
|
||||||
assertEquals("тест", answer3);
|
// assertEquals("тест", answer3);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
|
//
|
||||||
}
|
//}
|
Loading…
Reference in New Issue
Block a user