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

feat: init for java2 lab 02

parent e86ba804
Branches
No related merge requests found
Showing
with 799 additions and 221 deletions
......@@ -2,9 +2,10 @@
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>lab10v2</artifactId>
<groupId>cz.vsb.fei.java2</groupId>
<artifactId>java2-lab02-v2</artifactId>
<version>0.0.1-SNAPHOST</version>
<name>java2-lab02-v2</name>
<packaging>jar</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
......
......@@ -31,8 +31,7 @@ public class App extends Application {
try {
this.primaryStage = primaryStage;
switchToMenu();
primaryStage.resizableProperty().set(false);
primaryStage.setTitle("Java 1 - 1th laboratory");
primaryStage.setTitle("Java 2 - 2th laboratory");
primaryStage.show();
// Exit program when main window is closed
primaryStage.setOnCloseRequest(this::exitProgram);
......
......@@ -13,15 +13,15 @@ public class DbConnector {
private static final String JDBC_CONECTIN_STRING = "jdbc:h2:file:./scoreDB";
public static List<Score> getAll() {
public List<Score> getAll() {
return queryScore("select * from scores;");
}
public static List<Score> getFirstTen() {
public List<Score> getFirstTen() {
return queryScore("select * from scores order by points desc limit 10;");
}
private static List<Score> queryScore(String query) {
private List<Score> queryScore(String query) {
List<Score> result = new ArrayList<>();
try (Connection con = DriverManager.getConnection(JDBC_CONECTIN_STRING);
Statement stm = con.createStatement();
......@@ -35,7 +35,7 @@ public class DbConnector {
return result;
}
public static void createTable() {
public void createTable() {
try (Connection con = DriverManager.getConnection(JDBC_CONECTIN_STRING);
Statement stm = con.createStatement();) {
stm.executeUpdate("CREATE TABLE if not exists scores (nick VARCHAR(50) NOT NULL, points INT NOT NULL);");
......@@ -44,7 +44,7 @@ public class DbConnector {
}
}
public static void insertScore(Score score) {
public void insertScore(Score score) {
try (Connection con = DriverManager.getConnection(JDBC_CONECTIN_STRING);
PreparedStatement stm = con.prepareStatement("INSERT INTO scores VALUES (?, ?)");) {
stm.setString(1, score.getName());
......
......@@ -67,17 +67,17 @@ public class MainScreenController {
void btnGenerateScoreAction(ActionEvent event) {
Score score = Score.generate();
this.scores.getItems().add(score);
DbConnector.insertScore(score);
ScoreStorageFactory.getInstance().insertScore(score);
}
@FXML
void btnLoadAllAction(ActionEvent event) {
updateScoreTable(DbConnector.getAll());
updateScoreTable(ScoreStorageFactory.getInstance().getAll());
}
@FXML
void btnLoadFirstTenAction(ActionEvent event) {
updateScoreTable(DbConnector.getFirstTen());
updateScoreTable(ScoreStorageFactory.getInstance().getFirstTen());
}
private void updateScoreTable(List<Score> scores) {
......@@ -101,8 +101,8 @@ public class MainScreenController {
private void initDB() {
//Stream.generate(Score::generate).limit(10).toList();
DbConnector.createTable();
scores.getItems().addAll(DbConnector.getAll());
ScoreStorageFactory.getInstance().createTable();
scores.getItems().addAll(ScoreStorageFactory.getInstance().getAll());
}
}
package lab;
public class ScoreStorageFactory {
private static DbConnector instance;
public static DbConnector getInstance() {
if(instance == null) {
instance = new DbConnector();
}
return instance;
}
}
......@@ -13,7 +13,7 @@
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.text.Font?>
<BorderPane fx:id="menuPanel" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="456.0" prefWidth="711.0" xmlns="http://javafx.com/javafx/21" xmlns:fx="http://javafx.com/fxml/1" fx:controller="lab.MainScreenController">
<BorderPane fx:id="menuPanel" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="547.0" prefWidth="804.0" xmlns="http://javafx.com/javafx/21" xmlns:fx="http://javafx.com/fxml/1" fx:controller="lab.MainScreenController">
<top>
<HBox prefWidth="200.0" BorderPane.alignment="CENTER">
<children>
......@@ -29,45 +29,47 @@
</font></Button>
</bottom>
<center>
<HBox prefHeight="100.0" prefWidth="200.0" BorderPane.alignment="CENTER">
<VBox prefHeight="200.0" prefWidth="100.0" BorderPane.alignment="CENTER">
<children>
<RadioButton fx:id="easy" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" styleClass="difficultButton" text="Easy" HBox.hgrow="ALWAYS">
<toggleGroup>
<ToggleGroup fx:id="difficult" />
</toggleGroup>
<HBox.margin>
<Insets bottom="20.0" left="20.0" right="20.0" top="20.0" />
</HBox.margin>
</RadioButton>
<RadioButton fx:id="medium" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" selected="true" styleClass="difficultButton" text="Medium" toggleGroup="$difficult" HBox.hgrow="ALWAYS">
<HBox.margin>
<Insets bottom="20.0" left="20.0" right="20.0" top="20.0" />
</HBox.margin>
</RadioButton>
<RadioButton fx:id="hard" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" styleClass="difficultButton" text="Hard" toggleGroup="$difficult" HBox.hgrow="ALWAYS">
<HBox.margin>
<Insets bottom="20.0" left="20.0" right="20.0" top="20.0" />
</HBox.margin>
</RadioButton>
</children>
</HBox>
</center>
<right>
<VBox prefHeight="287.0" prefWidth="159.0" BorderPane.alignment="CENTER">
<children>
<TableView fx:id="scores" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308">
<columns>
<TableColumn fx:id="nickColumn" prefWidth="75.0" text="Nick" />
<TableColumn fx:id="pointsColumn" prefWidth="75.0" text="Points" />
</columns>
<columnResizePolicy>
<TableView fx:constant="CONSTRAINED_RESIZE_POLICY" />
</columnResizePolicy>
</TableView>
<Button fx:id="btnGenerateScore" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#btnGenerateScoreAction" text="Generate new score" />
<Button fx:id="btnLoadAll" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#btnLoadAllAction" text="Load all from DB" />
<Button fx:id="btnLoadFirstTen" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#btnLoadFirstTenAction" text="Load first 10 from DB" />
<HBox>
<children>
<RadioButton fx:id="easy" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" styleClass="difficultButton" text="Easy" HBox.hgrow="ALWAYS">
<toggleGroup>
<ToggleGroup fx:id="difficult" />
</toggleGroup>
<HBox.margin>
<Insets bottom="20.0" left="20.0" right="20.0" top="20.0" />
</HBox.margin>
</RadioButton>
<RadioButton fx:id="medium" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" selected="true" styleClass="difficultButton" text="Medium" toggleGroup="$difficult" HBox.hgrow="ALWAYS">
<HBox.margin>
<Insets bottom="20.0" left="20.0" right="20.0" top="20.0" />
</HBox.margin>
</RadioButton>
<RadioButton fx:id="hard" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" styleClass="difficultButton" text="Hard" toggleGroup="$difficult" HBox.hgrow="ALWAYS">
<HBox.margin>
<Insets bottom="20.0" left="20.0" right="20.0" top="20.0" />
</HBox.margin>
</RadioButton>
</children>
</HBox>
<VBox>
<children>
<TableView fx:id="scores" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="2000.0">
<columns>
<TableColumn fx:id="nickColumn" prefWidth="75.0" text="Nick" />
<TableColumn fx:id="pointsColumn" prefWidth="75.0" text="Points" />
</columns>
<columnResizePolicy>
<TableView fx:constant="CONSTRAINED_RESIZE_POLICY" />
</columnResizePolicy>
</TableView>
<Button fx:id="btnGenerateScore" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#btnGenerateScoreAction" text="Generate new score" />
<Button fx:id="btnLoadAll" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#btnLoadAllAction" text="Load all from DB" />
<Button fx:id="btnLoadFirstTen" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#btnLoadFirstTenAction" text="Load first 10 from DB" />
</children>
</VBox>
</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.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 static org.junit.jupiter.api.Assertions.assertTrue;
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.hamcrest.Matcher;
import org.hamcrest.MatcherAssert;
import org.hamcrest.Matchers;
import org.junit.jupiter.api.Test;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;
class ClassStructureTest {
StructureHelper helper = new StructureHelper();
@Test
void dataImporterTest() throws URISyntaxException, IOException, IllegalAccessException, InvocationTargetException {
helper.classExist("DataImporter", false);
Class<?> d = helper.getClass("DataImporter", false);
}
@Test
void dataImporterDownloadTest() throws URISyntaxException, IOException, IllegalAccessException, InvocationTargetException {
helper.classExist("DataImporter", false);
Class<?> d = helper.getClass("DataImporter", false);
String src = helper.getSourceCode(d);
helper.hasMethod(d, ".*down.*", false, String.class);
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 dataImporterParseAllTest() throws URISyntaxException, IOException, IllegalAccessException, InvocationTargetException {
helper.classExist("DataImporter", false);
Class<?> d = helper.getClass("DataImporter", false);
String src = helper.getSourceCode(d);
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 personTest() throws URISyntaxException, IOException, IllegalAccessException, InvocationTargetException {
helper.classExist("Person", false);
Class<?> p = helper.getClass("Person", false);
}
@Test
void dataImporterParsePersonTest() throws URISyntaxException, IOException, IllegalAccessException, InvocationTargetException {
helper.classExist("DataImporter", false);
Class<?> d = helper.getClass("DataImporter", false);
String src = helper.getSourceCode(d);
helper.classExist("Person", 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 personAgeTest() throws URISyntaxException, IOException, IllegalAccessException, InvocationTargetException {
helper.classExist("DataImporter", false);
Class<?> d = helper.getClass("DataImporter", false);
helper.classExist("Person", 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 person50birthdayTest() throws URISyntaxException, IOException, IllegalAccessException, InvocationTargetException {
helper.classExist("DataImporter", false);
Class<?> d = helper.getClass("DataImporter", false);
String src = helper.getSourceCode(d);
helper.classExist("Person", 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 peronNextBirthdayTest() throws URISyntaxException, IOException, IllegalAccessException, InvocationTargetException {
helper.classExist("DataImporter", false);
Class<?> d = helper.getClass("DataImporter", false);
String src = helper.getSourceCode(d);
helper.classExist("Person", 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());
StructureHelper helper = StructureHelper.getInstance();
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,8 +41,25 @@ 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.");
}
......@@ -47,16 +67,23 @@ class StructureHelper {
public void classExist(String name) {
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");
assertTrue(
allClasses.stream()
.anyMatch(c -> caseSensitive ? c.endsWith(name) : c.toLowerCase().endsWith(name.toLowerCase())),
"Class/Interface " + name + " not found");
}
public void classExistRegexp(String name) {
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");
assertTrue(
allClasses.stream()
.anyMatch(c -> caseSensitive ? c.matches(name) : c.toLowerCase().matches(name.toLowerCase())),
"Class/Interface " + name + " not found");
}
public Class<?> getClassDirectly(String name) {
......@@ -66,23 +93,25 @@ class StructureHelper {
public Class<?> getClassRegexp(String name) {
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);
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.");
}
return loadClass(name, className);
}
public Class<?> getClass(String name) {
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);
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.");
}
......@@ -105,13 +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) {
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 (caseSensitive?f.getName().matches(propertyNameRegexp):f.getName().toLowerCase().matches(propertyNameRegexp.toLowerCase())) {
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 {
......@@ -119,18 +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) {
public void hasPropertyWithAnnotation(Class<?> classDef, String propertyNameRegexp, Class<?> annotation,
boolean caseSensitive) {
List<Field> fields = Arrays.asList(classDef.getDeclaredFields());
assertTrue(
fields.stream().filter(f -> caseSensitive?f.getName().matches(propertyNameRegexp):f.getName().toLowerCase().matches(propertyNameRegexp.toLowerCase()))
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 "
......@@ -140,11 +185,14 @@ 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 -> caseSensitive?m.getName().matches(methodName):m.getName().toLowerCase().matches(methodName.toLowerCase()))
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());
}
......@@ -152,25 +200,35 @@ class StructureHelper {
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) {
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 -> 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()))
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:"
+ Arrays.asList(params).stream().map(Class::getName).collect(Collectors.joining(", ")));
}
public Method getMethod(Class<?> interfaceDef, String methodName,Class<?> returnType, Class<?>... params) {
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) {
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 -> caseSensitive?m.getName().matches(methodName):m.getName().toLowerCase().matches(methodName.toLowerCase()))
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()) {
......@@ -185,10 +243,11 @@ 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 -> caseSensitive?m.getName().matches(methodNameRegexp):m.getName().toLowerCase().matches(methodNameRegexp.toLowerCase())).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 {
......@@ -211,8 +270,10 @@ class StructureHelper {
public long countClassesRegexp(String classNameRegexp) {
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();
return getNameOfAllClasses().stream().filter(className -> caseSensitive ? className.matches(classNameRegexp)
: className.toLowerCase().matches(classNameRegexp.toLowerCase())).count();
}
public void hasConstructor(Class<?> classDef, Class<?>... params) {
......@@ -234,51 +295,106 @@ class StructureHelper {
}
return foundConstructors.get(0);
}
public void hasMethodRegexp(Class<?> interfaceDef, String methodNameRegexp, Class<?> returnType,
Class<?>... params) {
hasMethodRegexp(interfaceDef, methodNameRegexp, true, returnType, params);
hasMethodRegexp(interfaceDef, methodNameRegexp, true, returnType, params);
}
public void hasMethodRegexp(Class<?> interfaceDef, String methodNameRegexp, boolean caseSensitive, Class<?> returnType,
Class<?>... 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 -> caseSensitive?m.getName().matches(methodNameRegexp):m.getName().toLowerCase().matches(methodNameRegexp.toLowerCase())),
assertTrue(
methods.stream()
.anyMatch(m -> caseSensitive ? m.getName().matches(methodNameRegexp)
: m.getName().toLowerCase().matches(methodNameRegexp.toLowerCase())),
"No method " + methodNameRegexp);
assertTrue(
methods.stream().filter(m -> caseSensitive?m.getName().matches(methodNameRegexp):m.getName().toLowerCase().matches(methodNameRegexp.toLowerCase()))
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) {
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 -> caseSensitive?m.getName().matches(methodNameRegexp):m.getName().toLowerCase().matches(methodNameRegexp.toLowerCase())),
assertTrue(
methods.stream()
.anyMatch(m -> caseSensitive ? m.getName().matches(methodNameRegexp)
: m.getName().toLowerCase().matches(methodNameRegexp.toLowerCase())),
"No method " + methodNameRegexp);
return methods.stream().filter(m -> caseSensitive?m.getName().matches(methodNameRegexp):m.getName().toLowerCase().matches(methodNameRegexp.toLowerCase()))
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) {
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 -> 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()))
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))
......@@ -287,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));
......@@ -308,10 +428,14 @@ 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 -> caseSensitive?m.getName().matches(methodName):m.getName().toLowerCase().matches(methodName.toLowerCase())), "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