Skip to content
Snippets Groups Projects
Commit 30479247 authored by jez04's avatar jez04
Browse files

feat: base changes for java2

parent 2e6f8afd
No related merge requests found
Showing
with 1002 additions and 108 deletions
......@@ -2,8 +2,8 @@
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>vsb-cs-java1</groupId>
<artifactId>lab11v1</artifactId>
<groupId>vsb-cs-java2</groupId>
<artifactId>java2lab02v1</artifactId>
<version>0.0.1-SNAPHOST</version>
<packaging>jar</packaging>
<properties>
......@@ -60,6 +60,12 @@
<version>0.10.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest</artifactId>
<version>3.0</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
......
......@@ -15,9 +15,6 @@ import javafx.stage.WindowEvent;
*/
public class App extends Application {
static {
System.out.println("aaa");
}
private GameController gameController;
public static void main(String[] args) {
launch(args);
......@@ -32,8 +29,8 @@ public class App extends Application {
GameController gameController = gameLoader.getController();
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.resizableProperty().set(false);
primaryStage.setTitle("Java 1 - 1th laboratory");
// primaryStage.resizableProperty().set(false);
primaryStage.setTitle("Java 2 - 2nd laboratory");
primaryStage.show();
// Exit program when main window is closed
primaryStage.setOnCloseRequest(this::exitProgram);
......
......@@ -13,7 +13,7 @@ public class BulletAnimated extends Bullet {
private static final double SIZE = 40;
private final Point2D initVelocity;
private Cannon cannon;
private Image image = new Image(this.getClass().getResourceAsStream("fireball-transparent.gif"));
private static Image image = new Image(BulletAnimated.class.getResourceAsStream("fireball-transparent.gif"));
private List<HitListener> hitListeners =
new ArrayList<>();
......
package lab;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.regex.MatchResult;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
public class DataImporter {
private static final Pattern personTextPattern = Pattern.compile("\\{[^\\{\\}]*address");
private static final Pattern firstNamePattern = Pattern.compile("\"firstname\":\"([\\p{IsAlphabetic}']+)\"");
private static final Pattern lastNamePattern = Pattern.compile("\"lastname\":\"([\\p{IsAlphabetic}']+)\"");
private static final Pattern datePattern = Pattern.compile("\"birthday\":\"(\\d{4}-\\d{2}-\\d{2})\"");
private static final DateTimeFormatter czechDate = DateTimeFormatter.ofPattern("dd. MM. YYYY");
public static void main(String[] args) {
importPlayers();
}
public static void importPlayers() {
List<Person> persons = parseData(downloadText()).stream().map(DataImporter::parsePerson).toList();
for (Person person : persons) {
System.out.printf("%s %s (%s): age=%d, 50th: %s , next in: %d%n"
, person.getFirstName(), person.getLastName()
, person.getDayOfBirth().format(czechDate)
, person.getAge()
, person.get50thBirthDay().format(czechDate)
, person.getDaysToBirthday());
}
}
public static String downloadText() {
try {
URL url = new URI("https://fakerapi.it/api/v2/persons?_quantity=20").toURL();
try (InputStream is = url.openStream()) {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(is));
return bufferedReader.lines().collect(Collectors.joining("\n"));
}
} catch (URISyntaxException | IOException e) {
e.printStackTrace();
return "";
}
}
public static List<String> parseData(String data) {
Matcher matcher = personTextPattern.matcher(data);
return matcher.results().map(MatchResult::group).toList();
}
public static Person parsePerson(String personText) {
String firstName = firstNamePattern.matcher(personText).results().map(result -> result.group(1)).findAny()
.orElse("");
String lastName = lastNamePattern.matcher(personText).results().map(result -> result.group(1)).findAny()
.orElse("");
LocalDate date = datePattern.matcher(personText).results().map(result -> result.group(1)).map(text -> LocalDate.parse(text, DateTimeFormatter.ISO_DATE)).findAny()
.orElse(LocalDate.EPOCH);
return new Person(firstName, lastName, date);
}
}
package lab;
import java.time.Duration;
import java.time.LocalDate;
import java.time.Period;
import java.time.temporal.ChronoUnit;
public class Person {
private String firstName;
private String lastName;
private LocalDate dayOfBirth;
public Person(String firstName, String lastName, LocalDate dayOfBirth) {
super();
this.firstName = firstName;
this.lastName = lastName;
this.dayOfBirth = dayOfBirth;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getFirstName() {
return firstName;
}
public LocalDate getDayOfBirth() {
return dayOfBirth;
}
public int getAge() {
return Period.between(dayOfBirth, LocalDate.now()).getYears();
}
public static void main(String[] args) {
Person p = new Person("", "", LocalDate.now().minusDays(3700));
System.out.println(p.getAge());
System.out.println(p.getDaysToBirthday());
}
public LocalDate get50thBirthDay() {
return dayOfBirth.plusYears(50);
}
public long getDaysToBirthday() {
LocalDate nextBirthday = dayOfBirth.withYear(LocalDate.now().getYear());
if(nextBirthday.isBefore(LocalDate.now())){
nextBirthday = nextBirthday.plusYears(1);
}
return ChronoUnit.DAYS.between(LocalDate.now(), nextBirthday);
}
}
......@@ -4,18 +4,18 @@
<?import javafx.scene.Cursor?>
<?import javafx.scene.canvas.Canvas?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.Slider?>
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.StackPane?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.text.Font?>
<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="471.0" prefWidth="901.0" xmlns="http://javafx.com/javafx/21" xmlns:fx="http://javafx.com/fxml/1" fx:controller="lab.GameController">
<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="421.0" prefWidth="849.0" xmlns="http://javafx.com/javafx/21" xmlns:fx="http://javafx.com/fxml/1" fx:controller="lab.GameController">
<bottom>
<HBox alignment="TOP_CENTER" prefHeight="100.0" prefWidth="200.0" BorderPane.alignment="CENTER">
<HBox alignment="TOP_CENTER" prefHeight="66.0" prefWidth="866.0" BorderPane.alignment="CENTER">
<children>
<Slider fx:id="angle" majorTickUnit="15.0" max="90.0" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minorTickCount="5" showTickLabels="true" showTickMarks="true" HBox.hgrow="ALWAYS" />
<Button mnemonicParsing="false" onAction="#fire" style="-fx-background-color: RED;" text="Fire" textAlignment="CENTER">
......@@ -36,18 +36,18 @@
</children>
</HBox>
</bottom>
<center>
<Canvas fx:id="canvas" height="306.0" width="582.0" BorderPane.alignment="CENTER">
<left>
<StackPane style="-fx-border-image-width: 3px; -fx-border-style: SOLID;" BorderPane.alignment="CENTER">
<BorderPane.margin>
<Insets />
</BorderPane.margin>
</Canvas>
</center>
<top>
<Label fx:id="hits" text="Hit count: 0" textAlignment="CENTER" BorderPane.alignment="CENTER" />
</top>
<right>
<VBox maxHeight="1.7976931348623157E308" maxWidth="-Infinity" BorderPane.alignment="CENTER">
<children>
<Canvas fx:id="canvas" height="306.0" style="-fx-border-width: 3px; -fx-border-style: SOLID; -fx-border-color: RGB(100.0,0.0,0.0);" width="582.0" StackPane.alignment="TOP_LEFT" />
</children>
</StackPane>
</left>
<center>
<VBox maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" BorderPane.alignment="CENTER">
<children>
<TableView fx:id="scores" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308">
<columns>
......@@ -63,5 +63,5 @@
<Button fx:id="btnLoadFirstTen" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#btnLoadFirstTenAction" text="Load First 10 from DB" />
</children>
</VBox>
</right>
</center>
</BorderPane>
package jez04.structure.test;
import java.util.Arrays;
import java.util.List;
import org.hamcrest.BaseMatcher;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
public class AllOfContinue<T> extends BaseMatcher<T> {
private final List<Matcher<? super T>> matchers;
@SafeVarargs
public AllOfContinue(Matcher<? super T> ... matchers) {
this(Arrays.asList(matchers));
}
public AllOfContinue(List<Matcher<? super T>> matchers) {
this.matchers = matchers;
}
@Override
public boolean matches(Object o) {
for (Matcher<? super T> matcher : matchers) {
if (!matcher.matches(o)) {
// matcher.describeMismatch(o, mismatch);
return false;
}
}
return true;
}
@Override
public void describeTo(Description description) {
description.appendList("(", " " + "and" + " ", ")", matchers);
}
}
package jez04.structure.test;
import org.hamcrest.Description;
public class ClassExist extends StructureMatcher<String> {
private String className;
private boolean useRegExp;
private boolean caseSensitive;
public ClassExist(String className) {
this(className, true, false);
}
public ClassExist(String className, boolean caseSensitive, boolean useRegExp) {
this.className = className;
this.useRegExp = useRegExp;
this.caseSensitive = caseSensitive;
}
@Override
public boolean matches(Object actual) {
if (useRegExp) {
return structureHelper.getAllClasses().stream().anyMatch(
c -> caseSensitive ? c.matches(className) : c.toLowerCase().matches(className.toLowerCase()));
} else {
return structureHelper.getAllClasses().stream().anyMatch(
c -> caseSensitive ? c.endsWith(className) : c.toLowerCase().endsWith(className.toLowerCase()));
}
}
@Override
public void describeTo(Description description) {
description.appendText(String.format("class/interface with name '%s' comparsion params(%s %s) exists", className,
caseSensitive ? "" : "no case sensitive", useRegExp ? "using regexp" : ""));
}
@Override
public void describeMismatch(Object item, Description description) {
description.appendValueList("no class match from:\n ", "\n ", "", structureHelper.getAllClasses());
}
}
package jez04.structure.test;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.endsWith;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.startsWith;
import static org.hamcrest.Matchers.stringContainsInOrder;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URISyntaxException;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.List;
import org.junit.jupiter.api.Test;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
class ClassStructureTest {
StructureHelper helper = new StructureHelper();
StructureHelper helper = StructureHelper.getInstance();
@Test
void gameControllerExistenceTest() {
helper.classExist("GameController");
void dataImporterTest() throws URISyntaxException, IOException, IllegalAccessException, InvocationTargetException {
assertThat("", new ClassExist(".*Data.*", false, true));
Class<?> c = helper.getClassRegexp(".*Data.*");
}
@Test
void gameControllerFxmlTest() {
helper.classExist("GameController");
Class<?> c = helper.getClass("GameController");
helper.hasPropertyWithAnnotation(c, ".*", FXML.class);
void dataImporterDownloadTest() throws URISyntaxException, IOException, IllegalAccessException, InvocationTargetException {
assertThat("", new ClassExist(".*Data.*", false, true));
Class<?> d = helper.getClassRegexp(".*Data.*");
assertThat(d, new HasMethod(".*down.*", String.class).useRegExp(true).caseSensitive(false));
Method download = helper.getMethod(d, ".*down.*", false, String.class);
String downloadedText = (String) download.invoke(null);
assertThat(downloadedText, allOf(
endsWith("}]}"),
startsWith("{\"status\":\"OK\""),
stringContainsInOrder("firstname"),
stringContainsInOrder("lastname"),
stringContainsInOrder("birthday")
));
}
@Test
void gameControllerButtonActionMethodTest() {
helper.classExist("GameController");
Class<?> c = helper.getClass("GameController");
long count = helper.countMethodRegexp(c, ".*", void.class, ActionEvent.class);
assertTrue(count > 1, "Only " + count+ " method handling button click found. Expected more then 1");
void dataImporterParseAllTest() throws URISyntaxException, IOException, IllegalAccessException, InvocationTargetException {
assertThat("", new ClassExist(".*Data.*", false, true));
Class<?> d = helper.getClassRegexp(".*Data.*");
helper.hasMethod(d, ".*parse.*", false, List.class, String.class);
Method parse = helper.getMethod(d, ".*parse.*", false, List.class, String.class);
List<String> texts = (List<String>) parse.invoke(null, "{\"id\":1,\"firstname\":\"Tatum\",\"lastname\":\"Block\",\"email\":\"lonnie.bergstrom@stoltenberg.com\",\"phone\":\"+12397191764\",\"birthday\":\"1946-11-06\",\"gender\":\"male\",\"address\":{");
assertThat(texts, not(empty()));
}
@Test
void gameControllerTableViewTest() {
helper.classExist("GameController");
Class<?> c = helper.getClass("GameController");
helper.hasProperty(c, ".*", TableView.class, false);
}
@Test
void gameControllerTableColumnTest() {
helper.classExist("GameController");
Class<?> c = helper.getClass("GameController");
helper.hasProperty(c, ".*", TableColumn.class, false);
void personTest() throws URISyntaxException, IOException, IllegalAccessException, InvocationTargetException {
assertThat("", new ClassExist("Person", false, false));
Class<?> p = helper.getClass("Person", false);
}
@Test
void dbConnectorTest() {
helper.classExistRegexp(".*[Dd][Bb][cC]on.*");
}
void dataImporterParsePersonTest() throws URISyntaxException, IOException, IllegalAccessException, InvocationTargetException {
assertThat("", new ClassExist(".*Data.*", false, true));
Class<?> d = helper.getClassRegexp(".*Data.*");
@Test
void dbConnectorGetAllTest() {
helper.classExistRegexp(".*[Dd][Bb][cC]on.*");
Class<?> scoreClass = helper.getClassRegexp(".*[sS]core.*");
Class<?> c = helper.getClassRegexp(".*[Dd][Bb][cC]on.*");
helper.hasMethodRegexp(c, ".*[aA]ll.*", List.class);
helper.hasMethodRegexp(c, ".*[iI]nsert.*", void.class, scoreClass);
}
@Test
void dbConnectorInsertTest() {
helper.classExistRegexp(".*[Dd][Bb][cC]on.*");
Class<?> scoreClass = helper.getClassRegexp(".*[sS]core.*");
Class<?> c = helper.getClassRegexp(".*[Dd][Bb][cC]on.*");
helper.hasMethodRegexp(c, ".*[iI]nsert.*", void.class, scoreClass);
assertThat("", new ClassExist("Person", false, false));
Class<?> p = helper.getClass("Person", false);
helper.hasMethod(d, ".*parse.*", false, p, String.class);
Method parsePerson = helper.getMethod(d, ".*parse.*", false, p, String.class);
Object person = parsePerson.invoke(null, "{\"id\":1,\"firstname\":\"Tatum\",\"lastname\":\"Block\",\"email\":\"lonnie.bergstrom@stoltenberg.com\",\"phone\":\"+12397191764\",\"birthday\":\"1946-11-06\",\"gender\":\"male\",\"address\":{");
assertThat(person, notNullValue());
}
@Test
void dbConnectorContainsJdbcTest() throws URISyntaxException, IOException {
helper.classExistRegexp(".*[Dd][Bb][cC]on.*");
Class<?> c = helper.getClassRegexp(".*[Dd][Bb][cC]on.*");
String src = helper.getSourceCode(c);
assertTrue(src.contains("jdbc:"), "No usage of jdbc detect.");
void personAgeTest() throws URISyntaxException, IOException, IllegalAccessException, InvocationTargetException {
assertThat("", new ClassExist(".*Data.*", false, true));
Class<?> d = helper.getClassRegexp(".*Data.*");
assertThat("", new ClassExist("Person", false, false));
Class<?> p = helper.getClass("Person", false);
helper.hasMethod(d, ".*parse.*", false, p, String.class);
Method parsePerson = helper.getMethod(d, ".*parse.*", false, p, String.class);
Object person = parsePerson.invoke(null, "{\"id\":1,\"firstname\":\"Tatum\",\"lastname\":\"Block\",\"email\":\"lonnie.bergstrom@stoltenberg.com\",\"phone\":\"+12397191764\",\"birthday\":\"1946-11-06\",\"gender\":\"male\",\"address\":{");
assertThat(person, notNullValue());
Method age = helper.getMethod(p, ".*age.*", false, int.class);
int result = (int)age.invoke(person);
assertEquals(78, result , "Calculate wrong age.");
}
@Test
void dbConnectorContainsDriverManagerTest() throws URISyntaxException, IOException {
helper.classExistRegexp(".*[Dd][Bb][cC]on.*");
Class<?> c = helper.getClassRegexp(".*[Dd][Bb][cC]on.*");
String src = helper.getSourceCode(c);
assertTrue(src.contains("DriverManager"), "No usage of DriverManager detect.");
void person50birthdayTest() throws URISyntaxException, IOException, IllegalAccessException, InvocationTargetException {
assertThat("", new ClassExist(".*Data.*", false, true));
Class<?> d = helper.getClassRegexp(".*Data.*");
assertThat("", new ClassExist("Person", false, false));
Class<?> p = helper.getClass("Person", false);
helper.hasMethod(d, ".*parse.*", false, p, String.class);
Method parsePerson = helper.getMethod(d, ".*parse.*", false, p, String.class);
Object person = parsePerson.invoke(null, "{\"id\":1,\"firstname\":\"Tatum\",\"lastname\":\"Block\",\"email\":\"lonnie.bergstrom@stoltenberg.com\",\"phone\":\"+12397191764\",\"birthday\":\"1946-11-06\",\"gender\":\"male\",\"address\":{");
assertThat(person, notNullValue());
Method birth50 = helper.getMethod(p, ".*50.*", false, LocalDate.class);
LocalDate ldBirth50 = (LocalDate)birth50.invoke(person);
assertEquals(LocalDate.of(1996, 11, 06), ldBirth50 , "Calculate wrong 50th birthday.");
}
@Test
void dbConnectorContainsSqlTest() throws URISyntaxException, IOException {
helper.classExistRegexp(".*[Dd][Bb][cC]on.*");
Class<?> c = helper.getClassRegexp(".*[Dd][Bb][cC]on.*");
String src = helper.getSourceCode(c).toLowerCase();
assertTrue(src.contains("create "), "No usage of SQL create.");
assertTrue(src.contains("select "), "No usage of SQL select.");
assertTrue(src.contains("insert "), "No usage of SQL table.");
assertTrue(src.contains(" from "), "No usage of SQL from.");
assertTrue(src.contains(" table"), "No usage of SQL table.");
void personNextBirthdayTest() throws URISyntaxException, IOException, IllegalAccessException, InvocationTargetException {
assertThat("", new ClassExist(".*Data.*", false, true));
Class<?> d = helper.getClassRegexp(".*Data.*");
assertThat("", new ClassExist("Person", false, false));
Class<?> p = helper.getClass("Person", false);
helper.hasMethod(d, ".*parse.*", false, p, String.class);
Method parsePerson = helper.getMethod(d, ".*parse.*", false, p, String.class);
LocalDate bod =LocalDate.now().plusDays(338).minusYears(10);
Object person = parsePerson.invoke(null, "{\"id\":1,\"firstname\":\"Tatum\",\"lastname\":\"Block\",\"email\":\"lonnie.bergstrom@stoltenberg.com\",\"phone\":\"+12397191764\",\"birthday\":\""+ bod.format(DateTimeFormatter.ISO_DATE) +"\",\"gender\":\"male\",\"address\":{");
assertThat(person, notNullValue());
Method daysM = helper.getMethod(p, ".*days.*", false, long.class);
long days= (long)daysM.invoke(person);
assertEquals(338, days , "Calculate wrong days to next birthday.");
}
}
package jez04.structure.test;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.List;
import java.util.stream.Collectors;
import org.hamcrest.Description;
public class ContainsInnerClasses extends StructureMatcher<Class<?>> {
private String methodNameRegexp;
private boolean caseSensitive = true;
private boolean useRegExp = false;
private int count = 1;
private List<Class<?>> params;
public ContainsInnerClasses(String methodNameRegexp) {
this.methodNameRegexp = methodNameRegexp;
}
public ContainsInnerClasses caseSensitive(boolean caseSensitive) {
this.caseSensitive = caseSensitive;
return this;
}
public ContainsInnerClasses count(int count) {
this.count = count;
return this;
}
public ContainsInnerClasses useRegExp(boolean useRegExp) {
this.useRegExp = useRegExp;
return this;
}
@Override
public boolean matches(Object actual) {
if (actual instanceof Class c) {
long lamdaCount = structureHelper.countMethodRegexp(c, "lambda\\$.*");
long innerClassCount = structureHelper.countClassesRegexp(c.getCanonicalName()+"\\$.*");
long methodRefCount = 0;
try {
methodRefCount = structureHelper.countMethodReference(c);
} catch (URISyntaxException | IOException e) {
System.out.println("Cannot count method references");
e.printStackTrace();
}
return lamdaCount + innerClassCount+methodRefCount >= count;
}
return false;
}
@Override
public void describeTo(Description description) {
params.stream().map(Class::getName).collect(Collectors.joining(", "));
description.appendText(
String.format("Class should have inner classses or lambdas name (regexp) of type %s %s %s with params types %s",
methodNameRegexp, caseSensitive ? "" : "ignore case", ""));
}
@Override
public void describeMismatch(Object item, Description description) {
if (item instanceof Class c) {
description.appendValueList("no method match from:\n ", "\n ", "", c.getDeclaredMethods());
} else {
description.appendText("mismatched item is not class type");
}
}
}
package jez04.structure.test;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.hamcrest.Description;
public class HasMethod extends StructureMatcher<Class<?>> {
private String methodNameRegexp;
private Class<?> returnType;
private boolean caseSensitive = true;
private boolean useRegExp = false;
private Boolean abstractTag = null;
private Boolean finalTag = null;
private int count = 1;
private List<Class<?>> params;
public HasMethod(String methodNameRegexp, Class<?> returnType, Class<?>... params) {
this.methodNameRegexp = methodNameRegexp;
this.returnType = returnType;
this.params = List.of(params);
}
public HasMethod caseSensitive(boolean caseSensitive) {
this.caseSensitive = caseSensitive;
return this;
}
public HasMethod abstractTag(Boolean abstractTag) {
this.abstractTag = abstractTag;
return this;
}
public HasMethod finalTag(Boolean finalTag) {
this.finalTag = finalTag;
return this;
}
public HasMethod count(int count) {
this.count = count;
return this;
}
public HasMethod useRegExp(boolean useRegExp) {
this.useRegExp = useRegExp;
return this;
}
@Override
public boolean matches(Object actual) {
if (actual instanceof Class c) {
List<Method> methods = Arrays.asList(c.getDeclaredMethods());
Stream<Method> streamOfMethods;
if (useRegExp) {
streamOfMethods = methods.stream().filter(m -> caseSensitive ? m.getName().matches(methodNameRegexp)
: m.getName().toLowerCase().matches(methodNameRegexp.toLowerCase()));
} else {
streamOfMethods = methods.stream().filter(m -> caseSensitive ? m.getName().endsWith(methodNameRegexp)
: m.getName().toLowerCase().endsWith(methodNameRegexp.toLowerCase()));
}
streamOfMethods = streamOfMethods
.filter(m -> returnType != null ? returnType.equals(m.getReturnType()) : true)
.filter(m -> finalTag != null ? Modifier.isAbstract(m.getModifiers()) == abstractTag.booleanValue()
: true)
.filter(m -> abstractTag != null ? Modifier.isFinal(m.getModifiers()) == finalTag.booleanValue()
: true);
long co = streamOfMethods.count();
return co >= count;
}
return false;
}
@Override
public void describeTo(Description description) {
params.stream().map(Class::getName).collect(Collectors.joining(", "));
description.appendText(
String.format("Class should have method name (regexp) of type %s %s %s with params types %s",
returnType, methodNameRegexp, caseSensitive ? "" : "ignore case", ""));
}
@Override
public void describeMismatch(Object item, Description description) {
if (item instanceof Class c) {
description.appendValueList("no method match from:\n ", "\n ", "", c.getDeclaredMethods());
} else {
description.appendText("mismatched item is not class type");
}
}
}
package jez04.structure.test;
import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Stream;
import org.hamcrest.Description;
public class HasProperty extends StructureMatcher<Class<?>> {
private String propertyNameRegexp;
private Class<?> type;
private Predicate<Type> genericTypeFilter;
private Predicate<Class<?>> typeFilter;
private Boolean array = false;
private boolean caseSensitive;
private Class<?> annotation = null;
private int count = 1;
public HasProperty(String propertyNameRegexp, Class<?> type, Boolean array) {
this(propertyNameRegexp, type, array, true);
}
public HasProperty(String propertyNameRegexp, Class<?> type, Boolean array, boolean caseSensitive) {
this.propertyNameRegexp = propertyNameRegexp;
this.type = type;
this.array = array;
this.caseSensitive = caseSensitive;
}
public HasProperty annotation(Class<?> annotation) {
this.annotation = annotation;
return this;
}
public HasProperty typeFilter(Predicate<Class<?>> typeFilter) {
this.typeFilter = typeFilter;
return this;
}
public HasProperty genericTypeFilter(Predicate<Type> genericTypeFilter) {
this.genericTypeFilter = genericTypeFilter;
return this;
}
public HasProperty count(int count) {
this.count = count;
return this;
}
@Override
public boolean matches(Object actual) {
if (actual instanceof Class c) {
Stream<?> streamOfResults;
List<Field> fields = Arrays.asList(c.getDeclaredFields());
Stream<Field> streamOfFields = fields.stream()
.filter(f -> caseSensitive ? f.getName().matches(propertyNameRegexp)
: f.getName().toLowerCase().matches(propertyNameRegexp.toLowerCase()))
.filter(f -> type != null ? f.getType().equals(type) : true)
.filter(f -> array != null ? f.getType().isAnnotation() == array.booleanValue() : true)
.filter(f -> genericTypeFilter != null ? genericTypeFilter.test(f.getGenericType()) : true)
.filter(f -> typeFilter != null ? typeFilter.test(f.getType()) : true);
streamOfResults = streamOfFields;
if (annotation != null) {
streamOfResults = streamOfFields.flatMap(f -> Arrays.asList(f.getAnnotations()).stream())
.map(a -> a.annotationType()).filter(a -> a.equals(annotation));
}
long actualCount = streamOfResults.count();
return this.count <= actualCount;
}
return false;
}
@Override
public void describeTo(Description description) {
description.appendText(String.format("Class should have field of type %s%s with name match regexp '%s'%s", type,
array != null && array ? "[]" : "", propertyNameRegexp, caseSensitive ? "" : "ignore case"));
}
@Override
public void describeMismatch(Object item, Description description) {
if (item instanceof Class c) {
description.appendValueList("none of", ", ", "match", c.getDeclaredFields());
} else {
description.appendText("mismatched item is not class type");
}
}
}
package jez04.structure.test;
import org.hamcrest.Description;
public class IsDescendatOf extends StructureMatcher<Class<?>> {
private String className;
public IsDescendatOf(String className) {
this.className = className;
}
@Override
public boolean matches(Object actual) {
if(actual instanceof Class c) {
return structureHelper.getClass(className).isAssignableFrom(c);
}
return false;
}
@Override
public void describeTo(Description description) {
description.appendText(String.format("cass shoud be descendant of %s", className));
}
}
package jez04.structure.test;
import org.hamcrest.Description;
public class IsInterface extends StructureMatcher<Class<?>> {
public IsInterface() {
}
@Override
public boolean matches(Object actual) {
if (actual instanceof Class c) {
return c.isInterface();
}
return false;
}
@Override
public void describeTo(Description description) {
description.appendText(String.format("value should be interface"));
}
}
package jez04.structure.test;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.FileVisitResult;
import java.nio.file.FileVisitor;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.LinkedList;
import java.util.List;
import java.util.regex.Pattern;
import org.hamcrest.Description;
public class ResourceContains extends StructureMatcher<String> {
private String regexp;
private boolean caseInsensitive;
private boolean srcFound;
private int count = 1;
public ResourceContains(String regexp, boolean caseInsensitive) {
this.regexp = regexp;
this.caseInsensitive = caseInsensitive;
}
public ResourceContains count(int count) {
this.count = count;
return this;
}
@Override
public boolean matches(Object actual) {
srcFound = true;
List<Path> foundResources = new LinkedList<>();
Pattern p;
if (caseInsensitive) {
p = Pattern.compile(regexp, Pattern.CASE_INSENSITIVE);
} else {
p = Pattern.compile(regexp);
}
try {
URL myClassUrl = StructureHelper.class.getResource(this.getClass().getSimpleName() + ".class");
Path classRoot = Paths.get(myClassUrl.toURI());
while (!"test-classes".equals(classRoot.getFileName().toString())
&& !"classes".equals(classRoot.getFileName().toString())) {
classRoot = classRoot.getParent();
}
Path resourcesRoot = classRoot.getParent().getParent().resolve(Paths.get("src", "main", "resources"));
System.out.println("resources root: " + resourcesRoot);
Files.walkFileTree(resourcesRoot, new FileVisitor<Path>() {
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
if (p.matcher(file.getFileName().toString()).matches()) {
foundResources.add(file);
}
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
return FileVisitResult.CONTINUE;
}
});
return foundResources.size() >= count;
} catch (URISyntaxException | IOException e) {
srcFound = false;
e.printStackTrace();
return false;
}
}
@Override
public void describeTo(Description description) {
description.appendText(String.format("Source code of class shoud contains regexp '%s'%s", regexp,
caseInsensitive ? " in case insensitive mode" : ""));
}
@Override
public void describeMismatch(Object item, Description description) {
if (srcFound) {
description
.appendText(String.format("source code of class %s do not contains substring that match reg exp"));
} else {
description.appendText(String.format("source code of class %s was not found"));
}
}
}
package jez04.structure.test;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.regex.Pattern;
import org.hamcrest.Description;
public class SrcContains extends StructureMatcher<Class<?>> {
private String regexp;
private boolean caseInsensitive;
private boolean srcFound;
public SrcContains(String regexp, boolean caseInsensitive) {
this.regexp = regexp;
this.caseInsensitive = caseInsensitive;
}
@Override
public boolean matches(Object actual) {
srcFound = true;
if (actual instanceof Class c) {
Pattern p = Pattern.compile(regexp);
if (caseInsensitive) {
p = Pattern.compile(regexp, Pattern.CASE_INSENSITIVE);
}
try {
return p.matcher(structureHelper.getSourceCode(c)).find();
} catch (URISyntaxException | IOException e) {
srcFound = false;
e.printStackTrace();
return false;
}
}
return false;
}
@Override
public void describeTo(Description description) {
description.appendText(String.format("Source code of class shoud contains regexp '%s'%s", regexp,
caseInsensitive ? " in case insensitive mode" : ""));
}
@Override
public void describeMismatch(Object item, Description description) {
if (srcFound) {
description
.appendText(String.format("source code of class %s do not contains substring that match reg exp", item));
} else {
description.appendText(String.format("source code of class %s was not found"));
}
}
}
......@@ -29,7 +29,10 @@ import java.util.function.Predicate;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.hamcrest.BaseMatcher;
import org.hamcrest.Description;
import org.junit.jupiter.api.Assertions;
import org.reflections.Configuration;
import org.reflections.Reflections;
......@@ -38,18 +41,49 @@ import org.reflections.util.ConfigurationBuilder;
class StructureHelper {
private static StructureHelper singeltonInstance;
public static StructureHelper getInstance() {
if (singeltonInstance == null) {
singeltonInstance = new StructureHelper();
}
return singeltonInstance;
}
Set<String> allClasses = getNameOfAllClasses();
private StructureHelper() {
/* hide public one */
}
public Set<String> getAllClasses() {
return allClasses;
}
public void isInterface(Class<?> c) {
assertTrue(c.isInterface(), c.getName() + " have to be interface.");
}
public void classExist(String name) {
assertTrue(allClasses.stream().anyMatch(c -> c.endsWith(name)), "Class/Interface " + name + " not found");
classExist(name, true);
}
public void classExist(String name, boolean caseSensitive) {
assertTrue(
allClasses.stream()
.anyMatch(c -> caseSensitive ? c.endsWith(name) : c.toLowerCase().endsWith(name.toLowerCase())),
"Class/Interface " + name + " not found");
}
public void classExistRegexp(String name) {
assertTrue(allClasses.stream().anyMatch(c -> c.matches(name)), "Class/Interface " + name + " not found");
classExistRegexp(name, true);
}
public void classExistRegexp(String name, boolean caseSensitive) {
assertTrue(
allClasses.stream()
.anyMatch(c -> caseSensitive ? c.matches(name) : c.toLowerCase().matches(name.toLowerCase())),
"Class/Interface " + name + " not found");
}
public Class<?> getClassDirectly(String name) {
......@@ -57,7 +91,13 @@ class StructureHelper {
}
public Class<?> getClassRegexp(String name) {
String className = allClasses.stream().filter(c -> c.matches(name)).findAny().orElse(null);
return getClassRegexp(name, true);
}
public Class<?> getClassRegexp(String name, boolean caseSensitive) {
String className = allClasses.stream()
.filter(c -> caseSensitive ? c.matches(name) : c.toLowerCase().matches(name.toLowerCase())).findAny()
.orElse(null);
if (className == null) {
Assertions.fail("Class " + name + " not found.");
}
......@@ -65,7 +105,13 @@ class StructureHelper {
}
public Class<?> getClass(String name) {
String className = allClasses.stream().filter(c -> c.endsWith(name)).findAny().orElse(null);
return getClass(name, true);
}
public Class<?> getClass(String name, boolean caseSensitive) {
String className = allClasses.stream()
.filter(c -> caseSensitive ? c.endsWith(name) : c.toLowerCase().endsWith(name.toLowerCase())).findAny()
.orElse(null);
if (className == null) {
Assertions.fail("Class " + name + " not found.");
}
......@@ -88,10 +134,27 @@ class StructureHelper {
}
}
public org.hamcrest.Matcher<Class<?>> hasProperty(String propertyNameRegexp, Class<?> type, boolean array) {
return new HasProperty(propertyNameRegexp, type, array);
}
public void hasProperty(Class<?> classDef, String propertyNameRegexp, Class<?> type, boolean array) {
hasProperty(classDef, propertyNameRegexp, type, array, true);
}
public void hasProperty(Class<?> classDef, String propertyNameRegexp, Class<?> type, boolean array,
boolean caseSensitive) {
assertTrue(hasPropertyB(classDef, propertyNameRegexp, type, array, caseSensitive),
"No field " + propertyNameRegexp + " of type " + type.getName() + " (is array " + array + ") in class "
+ classDef.getName());
}
public boolean hasPropertyB(Class<?> classDef, String propertyNameRegexp, Class<?> type, boolean array,
boolean caseSensitive) {
List<Field> fields = Arrays.asList(classDef.getDeclaredFields());
assertTrue(fields.stream().anyMatch(f -> {
if (f.getName().matches(propertyNameRegexp)) {
return fields.stream().anyMatch(f -> {
if (caseSensitive ? f.getName().matches(propertyNameRegexp)
: f.getName().toLowerCase().matches(propertyNameRegexp.toLowerCase())) {
if (array) {
return f.getType().isArray() && f.getType().getComponentType().equals(type);
} else {
......@@ -99,14 +162,20 @@ class StructureHelper {
}
}
return false;
}), "No field " + propertyNameRegexp + " of type " + type.getName() + " (is array " + array + ") in class "
+ classDef.getName());
});
}
public void hasPropertyWithAnnotation(Class<?> classDef, String propertyNameRegexp, Class<?> annotation) {
hasPropertyWithAnnotation(classDef, propertyNameRegexp, annotation, true);
}
public void hasPropertyWithAnnotation(Class<?> classDef, String propertyNameRegexp, Class<?> annotation,
boolean caseSensitive) {
List<Field> fields = Arrays.asList(classDef.getDeclaredFields());
assertTrue(
fields.stream().filter(f -> f.getName().matches(propertyNameRegexp))
fields.stream()
.filter(f -> caseSensitive ? f.getName().matches(propertyNameRegexp)
: f.getName().toLowerCase().matches(propertyNameRegexp.toLowerCase()))
.flatMap(f -> Arrays.asList(f.getAnnotations()).stream()).map(a -> a.annotationType())
.anyMatch(a -> a.equals(annotation)),
"No field " + propertyNameRegexp + " with annotation " + annotation.getName() + " in class "
......@@ -114,19 +183,36 @@ class StructureHelper {
}
public void hasMethod(Class<?> interfaceDef, String methodName, Class<?> returnType) {
hasMethod(interfaceDef, methodName, returnType, true);
}
public void hasMethod(Class<?> interfaceDef, String methodName, Class<?> returnType, boolean caseSensitive) {
List<Method> methods = Arrays.asList(interfaceDef.getDeclaredMethods());
assertTrue(methods.stream().anyMatch(m -> m.getName().contains(methodName)), "No method " + methodName);
assertTrue(
methods.stream().filter(m -> m.getName().contains(methodName))
methods.stream()
.filter(m -> caseSensitive ? m.getName().matches(methodName)
: m.getName().toLowerCase().matches(methodName.toLowerCase()))
.anyMatch(m -> m.getReturnType().equals(returnType)),
"Method " + methodName + " not return " + returnType.getName());
}
public void hasMethod(Class<?> interfaceDef, String methodName, Class<?> returnType, Class<?>... params) {
hasMethod(interfaceDef, methodName, true, returnType, params);
}
public void hasMethod(Class<?> interfaceDef, String methodName, boolean caseSensitive, Class<?> returnType,
Class<?>... params) {
List<Method> methods = Arrays.asList(interfaceDef.getDeclaredMethods());
assertTrue(methods.stream().anyMatch(m -> m.getName().contains(methodName)), "No method " + methodName);
assertTrue(
methods.stream().filter(m -> m.getName().contains(methodName))
methods.stream()
.anyMatch(m -> caseSensitive ? m.getName().matches(methodName)
: m.getName().toLowerCase().matches(methodName.toLowerCase())),
"No method " + methodName);
assertTrue(
methods.stream()
.filter(m -> caseSensitive ? m.getName().matches(methodName)
: m.getName().toLowerCase().matches(methodName.toLowerCase()))
.filter(m -> m.getReturnType().equals(returnType))
.anyMatch(m -> Arrays.asList(m.getParameterTypes()).containsAll(Arrays.asList(params))),
"Method " + methodName + " has no all parrams:"
......@@ -134,8 +220,15 @@ class StructureHelper {
}
public Method getMethod(Class<?> interfaceDef, String methodName, Class<?> returnType, Class<?>... params) {
return getMethod(interfaceDef, methodName, true, returnType, params);
}
public Method getMethod(Class<?> interfaceDef, String methodName, boolean caseSensitive, Class<?> returnType,
Class<?>... params) {
List<Method> methods = Arrays.asList(interfaceDef.getDeclaredMethods());
List<Method> foundMethods = methods.stream().filter(m -> m.getName().contains(methodName))
List<Method> foundMethods = methods.stream()
.filter(m -> caseSensitive ? m.getName().matches(methodName)
: m.getName().toLowerCase().matches(methodName.toLowerCase()))
.filter(m -> m.getReturnType().equals(returnType))
.filter(m -> Arrays.asList(m.getParameterTypes()).containsAll(Arrays.asList(params))).toList();
if (foundMethods.isEmpty()) {
......@@ -148,8 +241,13 @@ class StructureHelper {
}
public long countMethodRegexp(Class<?> interfaceDef, String methodNameRegexp) {
return countMethodRegexp(interfaceDef, methodNameRegexp, true);
}
public long countMethodRegexp(Class<?> interfaceDef, String methodNameRegexp, boolean caseSensitive) {
List<Method> methods = Arrays.asList(interfaceDef.getDeclaredMethods());
return methods.stream().filter(m -> m.getName().matches(methodNameRegexp)).count();
return methods.stream().filter(m -> caseSensitive ? m.getName().matches(methodNameRegexp)
: m.getName().toLowerCase().matches(methodNameRegexp.toLowerCase())).count();
}
public long countMethodReference(Class<?> interfaceDef) throws URISyntaxException, IOException {
......@@ -170,7 +268,12 @@ class StructureHelper {
}
public long countClassesRegexp(String classNameRegexp) {
return getNameOfAllClasses().stream().filter(className -> className.matches(classNameRegexp)).count();
return countClassesRegexp(classNameRegexp, true);
}
public long countClassesRegexp(String classNameRegexp, boolean caseSensitive) {
return getNameOfAllClasses().stream().filter(className -> caseSensitive ? className.matches(classNameRegexp)
: className.toLowerCase().matches(classNameRegexp.toLowerCase())).count();
}
public void hasConstructor(Class<?> classDef, Class<?>... params) {
......@@ -195,33 +298,103 @@ class StructureHelper {
public void hasMethodRegexp(Class<?> interfaceDef, String methodNameRegexp, Class<?> returnType,
Class<?>... params) {
hasMethodRegexp(interfaceDef, methodNameRegexp, true, returnType, params);
}
public void hasMethodRegexp(Class<?> interfaceDef, String methodNameRegexp, boolean caseSensitive,
Class<?> returnType, Class<?>... params) {
List<Method> methods = Arrays.asList(interfaceDef.getDeclaredMethods());
assertTrue(methods.stream().anyMatch(m -> m.getName().matches(methodNameRegexp)),
assertTrue(
methods.stream()
.anyMatch(m -> caseSensitive ? m.getName().matches(methodNameRegexp)
: m.getName().toLowerCase().matches(methodNameRegexp.toLowerCase())),
"No method " + methodNameRegexp);
assertTrue(
methods.stream().filter(m -> m.getName().matches(methodNameRegexp))
methods.stream()
.filter(m -> caseSensitive ? m.getName().matches(methodNameRegexp)
: m.getName().toLowerCase().matches(methodNameRegexp.toLowerCase()))
.filter(m -> m.getReturnType().equals(returnType))
.anyMatch(m -> Arrays.asList(m.getParameterTypes()).containsAll(Arrays.asList(params))),
"Method " + methodNameRegexp + " has no all parrams:"
+ Arrays.asList(params).stream().map(Class::getName).collect(Collectors.joining(", ")));
}
public boolean hasMethodRegexpTest(Class<?> interfaceDef, String methodNameRegexp, boolean caseSensitive,
Class<?> returnType, Class<?>... params) {
return hasMethodRegexpTest(interfaceDef, methodNameRegexp, caseSensitive, returnType, List.of(params));
}
public boolean hasMethodRegexpTest(Class<?> interfaceDef, String methodNameRegexp, boolean caseSensitive,
Class<?> returnType, List<Class<?>> params) {
List<Method> methods = Arrays.asList(interfaceDef.getDeclaredMethods());
if (!methods.stream().anyMatch(m -> caseSensitive ? m.getName().matches(methodNameRegexp)
: m.getName().toLowerCase().matches(methodNameRegexp.toLowerCase()))) {
return false;
}
return methods.stream()
.filter(m -> caseSensitive ? m.getName().matches(methodNameRegexp)
: m.getName().toLowerCase().matches(methodNameRegexp.toLowerCase()))
.filter(m -> m.getReturnType().equals(returnType))
.anyMatch(m -> Arrays.asList(m.getParameterTypes()).containsAll(params));
}
public long countMethodRegexp(Class<?> interfaceDef, String methodNameRegexp, Class<?> returnType,
Class<?>... params) {
return countMethodRegexp(interfaceDef, methodNameRegexp, true, returnType, params);
}
public long countMethodRegexp(Class<?> interfaceDef, String methodNameRegexp, boolean caseSensitive,
Class<?> returnType, Class<?>... params) {
List<Method> methods = Arrays.asList(interfaceDef.getDeclaredMethods());
assertTrue(methods.stream().anyMatch(m -> m.getName().matches(methodNameRegexp)),
assertTrue(
methods.stream()
.anyMatch(m -> caseSensitive ? m.getName().matches(methodNameRegexp)
: m.getName().toLowerCase().matches(methodNameRegexp.toLowerCase())),
"No method " + methodNameRegexp);
return methods.stream().filter(m -> m.getName().matches(methodNameRegexp))
return methods.stream()
.filter(m -> caseSensitive ? m.getName().matches(methodNameRegexp)
: m.getName().toLowerCase().matches(methodNameRegexp.toLowerCase()))
.filter(m -> m.getReturnType().equals(returnType))
.filter(m -> Arrays.asList(m.getParameterTypes()).containsAll(Arrays.asList(params))).count();
}
public boolean hasMethodTest(Class<?> interfaceDef, boolean finalTag, boolean abstractTag, String methodName,
boolean caseSensitive, Class<?> returnType, Class<?>... params) {
return hasMethodTest(interfaceDef, finalTag, abstractTag, methodName, caseSensitive, returnType, List.of(params));
}
public boolean hasMethodTest(Class<?> interfaceDef, boolean finalTag, boolean abstractTag, String methodName,
boolean caseSensitive, Class<?> returnType, List<Class<?>> params) {
List<Method> methods = Arrays.asList(interfaceDef.getDeclaredMethods());
if (!methods.stream().anyMatch(m -> caseSensitive ? m.getName().matches(methodName)
: m.getName().toLowerCase().matches(methodName.toLowerCase()))) {
return false;
}
return methods.stream()
.filter(m -> caseSensitive ? m.getName().matches(methodName)
: m.getName().toLowerCase().matches(methodName.toLowerCase()))
.filter(m -> m.getReturnType().equals(returnType)
&& (Modifier.isAbstract(m.getModifiers()) == abstractTag)
&& (Modifier.isFinal(m.getModifiers()) == finalTag))
.anyMatch(m -> Arrays.asList(m.getParameterTypes()).containsAll(params));
}
public void hasMethod(Class<?> interfaceDef, boolean finalTag, boolean abstractTag, String methodName,
Class<?> returnType, Class<?>... params) {
hasMethod(interfaceDef, finalTag, abstractTag, methodName, true, returnType, params);
}
public void hasMethod(Class<?> interfaceDef, boolean finalTag, boolean abstractTag, String methodName,
boolean caseSensitive, Class<?> returnType, Class<?>... params) {
List<Method> methods = Arrays.asList(interfaceDef.getDeclaredMethods());
assertTrue(methods.stream().anyMatch(m -> m.getName().contains(methodName)), "No method " + methodName);
assertTrue(
methods.stream().filter(m -> m.getName().contains(methodName))
methods.stream()
.anyMatch(m -> caseSensitive ? m.getName().matches(methodName)
: m.getName().toLowerCase().matches(methodName.toLowerCase())),
"No method " + methodName);
assertTrue(
methods.stream()
.filter(m -> caseSensitive ? m.getName().matches(methodName)
: m.getName().toLowerCase().matches(methodName.toLowerCase()))
.filter(m -> m.getReturnType().equals(returnType)
&& (Modifier.isAbstract(m.getModifiers()) == abstractTag)
&& (Modifier.isFinal(m.getModifiers()) == finalTag))
......@@ -230,6 +403,10 @@ class StructureHelper {
+ Arrays.asList(params).stream().map(Class::getName).collect(Collectors.joining(", ")));
}
public boolean isDescendatOf(Class<?> clazz, String interfaceName) {
return getClass(interfaceName).isAssignableFrom(clazz);
}
public void hasImplements(Class<?> clazz, String... interfaceNames) {
List<Class<?>> interfaces = new ArrayList<>();
Arrays.asList(interfaceNames).stream().map(name -> getClass(name)).forEach(c -> interfaces.add(c));
......@@ -249,8 +426,16 @@ class StructureHelper {
}
public void hasMethod(Class<?> interfaceDef, String methodName) {
hasMethod(interfaceDef, methodName, true);
}
public void hasMethod(Class<?> interfaceDef, String methodName, boolean caseSensitive) {
List<Method> methods = Arrays.asList(interfaceDef.getMethods());
assertTrue(methods.stream().anyMatch(m -> m.getName().contains(methodName)), "No method " + methodName);
assertTrue(
methods.stream()
.anyMatch(m -> caseSensitive ? m.getName().matches(methodName)
: m.getName().toLowerCase().matches(methodName.toLowerCase())),
"No method " + methodName);
}
public String getSourceCode(Class<?> clazz) throws URISyntaxException, IOException {
......
package jez04.structure.test;
public abstract class StructureMatcher<T> extends org.hamcrest.BaseMatcher<T>{
protected StructureHelper structureHelper = StructureHelper.getInstance();
}
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment