сделал допку
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,7 +1,5 @@
|
||||
|
||||
server.port=8080
|
||||
|
||||
# БД
|
||||
spring.datasource.url=jdbc:h2:file:./data;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
|
||||
spring.datasource.driver-class-name=org.h2.Driver
|
||||
spring.datasource.username=sa
|
||||
@@ -11,15 +9,17 @@ spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
|
||||
spring.jpa.hibernate.ddl-auto=validate
|
||||
spring.jpa.show-sql=false
|
||||
|
||||
# Liquibase
|
||||
spring.h2.console.enabled=true
|
||||
spring.h2.console.path=/h2-console
|
||||
spring.h2.console.settings.web-allow-others=true
|
||||
|
||||
spring.liquibase.enabled=true
|
||||
spring.liquibase.change-log=classpath:/db/changelog/db.changelog-master.yaml
|
||||
|
||||
spring.web.resources.static-locations=classpath:/static/
|
||||
spring.web.resources.add-mappings=true
|
||||
spring.mvc.throw-exception-if-no-handler-found=true
|
||||
|
||||
spring.thymeleaf.enabled=false
|
||||
|
||||
logging.level.org.springframework.web=DEBUG
|
||||
logging.level.com.example=DEBUG
|
||||
logging.level.org.springframework.web=INFO
|
||||
logging.level.com.example=INFO
|
||||
@@ -12,7 +12,6 @@ if (!frontDir.exists()) {
|
||||
} else {
|
||||
logger.quiet("Webapp dir is {}", frontDir.toString())
|
||||
|
||||
// Настраиваем node
|
||||
node {
|
||||
version = "22.17.1"
|
||||
npmVersion = "10.9.2"
|
||||
@@ -22,7 +21,6 @@ if (!frontDir.exists()) {
|
||||
nodeProjectDir = file("${frontDir}")
|
||||
}
|
||||
|
||||
// Задача для npm install
|
||||
task frontNpmInstall(type: NpmTask) {
|
||||
group = "front"
|
||||
description = "Installs npm dependencies"
|
||||
@@ -30,7 +28,6 @@ if (!frontDir.exists()) {
|
||||
args = ["install"]
|
||||
}
|
||||
|
||||
// Задача для npm build
|
||||
task frontNpmBuild(type: NpmTask) {
|
||||
group = "front"
|
||||
description = "Builds React app"
|
||||
@@ -43,7 +40,6 @@ if (!frontDir.exists()) {
|
||||
outputs.dir(frontDistDir)
|
||||
}
|
||||
|
||||
// Задача для копирования в ресурсы
|
||||
task copyFrontendToResources(type: Copy) {
|
||||
group = "front"
|
||||
description = "Copies built frontend to static resources"
|
||||
@@ -57,13 +53,10 @@ if (!frontDir.exists()) {
|
||||
}
|
||||
}
|
||||
|
||||
// Настраиваем зависимости
|
||||
copyFrontendToResources.dependsOn frontNpmBuild
|
||||
frontNpmBuild.dependsOn frontNpmInstall
|
||||
|
||||
// Интеграция со сборкой
|
||||
processResources.dependsOn copyFrontendToResources
|
||||
|
||||
// Для bootJar
|
||||
bootJar.dependsOn copyFrontendToResources
|
||||
}
|
||||
12
build.gradle
12
build.gradle
@@ -3,7 +3,7 @@ plugins {
|
||||
id 'org.springframework.boot' version '3.5.5'
|
||||
id 'io.spring.dependency-management' version '1.1.7'
|
||||
id 'org.liquibase.gradle' version '2.2.0'
|
||||
id 'com.github.node-gradle.node' version '7.0.2' // Для React
|
||||
id 'com.github.node-gradle.node' version '7.0.2'
|
||||
}
|
||||
|
||||
group = 'com.example'
|
||||
@@ -25,7 +25,6 @@ ext {
|
||||
h2Version = "2.3.232"
|
||||
postgresVersion = "42.7.3"
|
||||
|
||||
// НАСТРОЙКА ПРОФИЛЕЙ
|
||||
springProfiles = []
|
||||
if (project.hasProperty("front")) {
|
||||
springProfiles.add("front")
|
||||
@@ -49,16 +48,12 @@ dependencies {
|
||||
implementation 'org.springframework.boot:spring-boot-starter-actuator'
|
||||
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.5.0'
|
||||
|
||||
// Liquibase
|
||||
implementation "org.liquibase:liquibase-core:${liquibaseVersion}"
|
||||
|
||||
// БД в зависимости от профиля
|
||||
if (springProfiles.contains("prod")) {
|
||||
// Prod профиль - ТОЛЬКО PostgreSQL
|
||||
implementation "org.postgresql:postgresql:${postgresVersion}"
|
||||
logger.quiet("→ Added PostgreSQL dependency for PROD")
|
||||
} else {
|
||||
// Dev/Front профили - ТОЛЬКО H2
|
||||
implementation "com.h2database:h2:${h2Version}"
|
||||
logger.quiet("→ Added H2 dependency for DEV/FRONT")
|
||||
}
|
||||
@@ -67,7 +62,6 @@ dependencies {
|
||||
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
|
||||
}
|
||||
|
||||
// НАСТРОЙКА ПРОФИЛЕЙ ДЛЯ ЗАПУСКА
|
||||
bootRun {
|
||||
systemProperty "spring.profiles.active", currentProfiles
|
||||
}
|
||||
@@ -77,7 +71,6 @@ test {
|
||||
systemProperty "spring.profiles.active", currentProfiles
|
||||
}
|
||||
|
||||
// ПРАВКА application.properties ДЛЯ ПРОФИЛЕЙ
|
||||
processResources {
|
||||
filesMatching("**/application.properties") {
|
||||
filter { line ->
|
||||
@@ -86,17 +79,14 @@ processResources {
|
||||
}
|
||||
}
|
||||
|
||||
// ПОДКЛЮЧЕНИЕ МИГРАЦИЙ ТОЛЬКО ДЛЯ DEV
|
||||
if (springProfiles.contains("dev")) {
|
||||
apply from: "build.migrations.gradle"
|
||||
}
|
||||
|
||||
// НАСТРОЙКА ДЛЯ REACT (FRONT ПРОФИЛЬ)
|
||||
if (springProfiles.contains("front")) {
|
||||
apply from: "build.front.gradle"
|
||||
}
|
||||
|
||||
// ЗАДАЧИ ДЛЯ СБОРКИ JAR
|
||||
jar {
|
||||
enabled = true
|
||||
archiveFileName = "delivery-app.jar"
|
||||
|
||||
@@ -8,25 +8,20 @@ ext {
|
||||
timestamp = new Date().format("yyyy-MM-dd-HHmmss")
|
||||
}
|
||||
|
||||
// ОСНОВНАЯ КОНФИГУРАЦИЯ
|
||||
liquibase {
|
||||
activities {
|
||||
main {
|
||||
changelogFile "src/main/resources/db/changelog/db.changelog-master.yaml"
|
||||
|
||||
// Используем параметры URL для передачи пароля
|
||||
url "jdbc:h2:file:./data;user=sa;password="
|
||||
|
||||
driver "org.h2.Driver"
|
||||
logLevel "info"
|
||||
|
||||
// Не передаем username и password отдельно
|
||||
// Они уже в URL
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ЗАВИСИМОСТИ
|
||||
dependencies {
|
||||
liquibaseRuntime "org.liquibase:liquibase-core:${liquibaseVersion}"
|
||||
liquibaseRuntime "info.picocli:picocli:${picocliVersion}"
|
||||
@@ -36,7 +31,6 @@ dependencies {
|
||||
liquibaseRuntime sourceSets.main.output
|
||||
}
|
||||
|
||||
// ЗАДАЧА generateFull
|
||||
task generateFull {
|
||||
group = "migrations"
|
||||
description = "Generate changelog from existing database"
|
||||
@@ -54,7 +48,6 @@ task generateFull {
|
||||
finalizedBy generateChangelog
|
||||
}
|
||||
|
||||
// ЗАДАЧА generateDiff
|
||||
task generateDiff {
|
||||
group = "migrations"
|
||||
description = "Generate diff between DB and JPA entities"
|
||||
@@ -72,7 +65,6 @@ task generateDiff {
|
||||
finalizedBy diffChangelog
|
||||
}
|
||||
|
||||
// ЗАДАЧА ДЛЯ СТАТУСА - ИСПРАВЛЕННАЯ
|
||||
task migrationStatus {
|
||||
group = "migrations"
|
||||
description = "Show migration status"
|
||||
@@ -81,17 +73,15 @@ task migrationStatus {
|
||||
println "Checking migration status..."
|
||||
}
|
||||
|
||||
finalizedBy 'liquibaseStatus' // ИСПОЛЬЗУЕМ СТАНДАРТНУЮ ЗАДАЧУ LIQUIBASE
|
||||
finalizedBy 'liquibaseStatus'
|
||||
}
|
||||
|
||||
// ЗАДАЧА ДЛЯ SQL
|
||||
task updateSQL {
|
||||
group = "migrations"
|
||||
description = "Generate SQL without executing"
|
||||
|
||||
finalizedBy 'updateSQL' // СТАНДАРТНАЯ ЗАДАЧА LIQUIBASE
|
||||
finalizedBy 'updateSQL'
|
||||
}
|
||||
|
||||
// ВАЖНЫЕ ЗАВИСИМОСТИ
|
||||
diffChangelog.dependsOn compileJava
|
||||
update.dependsOn processResources
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
build/libs/delivery-app.jar
Normal file
BIN
build/libs/delivery-app.jar
Normal file
Binary file not shown.
Binary file not shown.
663
build/reports/problems/problems-report.html
Normal file
663
build/reports/problems/problems-report.html
Normal file
File diff suppressed because one or more lines are too long
@@ -0,0 +1,115 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
||||
<meta http-equiv="x-ua-compatible" content="IE=edge"/>
|
||||
<title>Test results - CustomerServiceTest</title>
|
||||
<link href="../css/base-style.css" rel="stylesheet" type="text/css"/>
|
||||
<link href="../css/style.css" rel="stylesheet" type="text/css"/>
|
||||
<script src="../js/report.js" type="text/javascript"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="content">
|
||||
<h1>CustomerServiceTest</h1>
|
||||
<div class="breadcrumbs">
|
||||
<a href="../index.html">all</a> >
|
||||
<a href="../packages/com.example.service.html">com.example.service</a> > CustomerServiceTest</div>
|
||||
<div id="summary">
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<div class="summaryGroup">
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<div class="infoBox" id="tests">
|
||||
<div class="counter">2</div>
|
||||
<p>tests</p>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="infoBox" id="failures">
|
||||
<div class="counter">0</div>
|
||||
<p>failures</p>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="infoBox" id="ignored">
|
||||
<div class="counter">0</div>
|
||||
<p>ignored</p>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="infoBox" id="duration">
|
||||
<div class="counter">0.559s</div>
|
||||
<p>duration</p>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="infoBox success" id="successRate">
|
||||
<div class="percent">100%</div>
|
||||
<p>successful</p>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="tab-container">
|
||||
<ul class="tabLinks">
|
||||
<li>
|
||||
<a href="#">Tests</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#">Standard error</a>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="tab">
|
||||
<h2>Tests</h2>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Test</th>
|
||||
<th>Duration</th>
|
||||
<th>Result</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tr>
|
||||
<td class="success">create_WhenValidData_ShouldCreateCustomer()</td>
|
||||
<td class="success">0.556s</td>
|
||||
<td class="success">passed</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="success">findById_WhenCustomerExists_ShouldReturnCustomer()</td>
|
||||
<td class="success">0.003s</td>
|
||||
<td class="success">passed</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="tab">
|
||||
<h2>Standard error</h2>
|
||||
<span class="code">
|
||||
<pre>Mockito is currently self-attaching to enable the inline-mock-maker. This will no longer work in future releases of the JDK. Please add Mockito as an agent to your build as described in Mockito's documentation: https://javadoc.io/doc/org.mockito/mockito-core/latest/org.mockito/org/mockito/Mockito.html#0.3
|
||||
WARNING: A Java agent has been loaded dynamically (/Users/floom/.gradle/caches/modules-2/files-2.1/net.bytebuddy/byte-buddy-agent/1.17.7/fbf3d6d649ed37fc9e9c59480a05be0a26e3c2da/byte-buddy-agent-1.17.7.jar)
|
||||
WARNING: If a serviceability tool is in use, please run with -XX:+EnableDynamicAgentLoading to hide this warning
|
||||
WARNING: If a serviceability tool is not in use, please run with -Djdk.instrument.traceUsage for more information
|
||||
WARNING: Dynamic loading of agents will be disallowed by default in a future release
|
||||
</pre>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div id="footer">
|
||||
<p>
|
||||
<div>
|
||||
<label class="hidden" id="label-for-line-wrapping-toggle" for="line-wrapping-toggle">Wrap lines
|
||||
<input id="line-wrapping-toggle" type="checkbox" autocomplete="off"/>
|
||||
</label>
|
||||
</div>Generated by
|
||||
<a href="https://www.gradle.org">Gradle 8.14.3</a> at 13 дек. 2025 г., 19:44:16</p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,121 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
||||
<meta http-equiv="x-ua-compatible" content="IE=edge"/>
|
||||
<title>Test results - DeliveryServiceTest</title>
|
||||
<link href="../css/base-style.css" rel="stylesheet" type="text/css"/>
|
||||
<link href="../css/style.css" rel="stylesheet" type="text/css"/>
|
||||
<script src="../js/report.js" type="text/javascript"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="content">
|
||||
<h1>DeliveryServiceTest</h1>
|
||||
<div class="breadcrumbs">
|
||||
<a href="../index.html">all</a> >
|
||||
<a href="../packages/com.example.service.html">com.example.service</a> > DeliveryServiceTest</div>
|
||||
<div id="summary">
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<div class="summaryGroup">
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<div class="infoBox" id="tests">
|
||||
<div class="counter">6</div>
|
||||
<p>tests</p>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="infoBox" id="failures">
|
||||
<div class="counter">0</div>
|
||||
<p>failures</p>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="infoBox" id="ignored">
|
||||
<div class="counter">0</div>
|
||||
<p>ignored</p>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="infoBox" id="duration">
|
||||
<div class="counter">0.051s</div>
|
||||
<p>duration</p>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="infoBox success" id="successRate">
|
||||
<div class="percent">100%</div>
|
||||
<p>successful</p>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="tab-container">
|
||||
<ul class="tabLinks">
|
||||
<li>
|
||||
<a href="#">Tests</a>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="tab">
|
||||
<h2>Tests</h2>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Test</th>
|
||||
<th>Duration</th>
|
||||
<th>Result</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tr>
|
||||
<td class="success">create_WhenValidData_ShouldCreateDelivery()</td>
|
||||
<td class="success">0.002s</td>
|
||||
<td class="success">passed</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="success">delete_WhenDeliveryExists_ShouldDeleteDelivery()</td>
|
||||
<td class="success">0.001s</td>
|
||||
<td class="success">passed</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="success">delete_WhenDeliveryNotExists_ShouldReturnFalse()</td>
|
||||
<td class="success">0.002s</td>
|
||||
<td class="success">passed</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="success">findAll_ShouldReturnAllDeliveries()</td>
|
||||
<td class="success">0.002s</td>
|
||||
<td class="success">passed</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="success">findById_WhenDeliveryExists_ShouldReturnDelivery()</td>
|
||||
<td class="success">0.042s</td>
|
||||
<td class="success">passed</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="success">update_WhenDeliveryExists_ShouldUpdateDelivery()</td>
|
||||
<td class="success">0.002s</td>
|
||||
<td class="success">passed</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div id="footer">
|
||||
<p>
|
||||
<div>
|
||||
<label class="hidden" id="label-for-line-wrapping-toggle" for="line-wrapping-toggle">Wrap lines
|
||||
<input id="line-wrapping-toggle" type="checkbox" autocomplete="off"/>
|
||||
</label>
|
||||
</div>Generated by
|
||||
<a href="https://www.gradle.org">Gradle 8.14.3</a> at 13 дек. 2025 г., 19:44:16</p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,136 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
||||
<meta http-equiv="x-ua-compatible" content="IE=edge"/>
|
||||
<title>Test results - OrderServiceTest</title>
|
||||
<link href="../css/base-style.css" rel="stylesheet" type="text/css"/>
|
||||
<link href="../css/style.css" rel="stylesheet" type="text/css"/>
|
||||
<script src="../js/report.js" type="text/javascript"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="content">
|
||||
<h1>OrderServiceTest</h1>
|
||||
<div class="breadcrumbs">
|
||||
<a href="../index.html">all</a> >
|
||||
<a href="../packages/com.example.service.html">com.example.service</a> > OrderServiceTest</div>
|
||||
<div id="summary">
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<div class="summaryGroup">
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<div class="infoBox" id="tests">
|
||||
<div class="counter">9</div>
|
||||
<p>tests</p>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="infoBox" id="failures">
|
||||
<div class="counter">0</div>
|
||||
<p>failures</p>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="infoBox" id="ignored">
|
||||
<div class="counter">0</div>
|
||||
<p>ignored</p>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="infoBox" id="duration">
|
||||
<div class="counter">0.053s</div>
|
||||
<p>duration</p>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="infoBox success" id="successRate">
|
||||
<div class="percent">100%</div>
|
||||
<p>successful</p>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="tab-container">
|
||||
<ul class="tabLinks">
|
||||
<li>
|
||||
<a href="#">Tests</a>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="tab">
|
||||
<h2>Tests</h2>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Test</th>
|
||||
<th>Duration</th>
|
||||
<th>Result</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tr>
|
||||
<td class="success">create_WhenCustomerNotFound_ShouldThrowException()</td>
|
||||
<td class="success">0.002s</td>
|
||||
<td class="success">passed</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="success">create_WhenValidData_ShouldCreateOrder()</td>
|
||||
<td class="success">0.041s</td>
|
||||
<td class="success">passed</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="success">delete_WhenOrderExists_ShouldDeleteOrder()</td>
|
||||
<td class="success">0.001s</td>
|
||||
<td class="success">passed</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="success">delete_WhenOrderNotExists_ShouldReturnFalse()</td>
|
||||
<td class="success">0.001s</td>
|
||||
<td class="success">passed</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="success">findAll_ShouldReturnAllOrders()</td>
|
||||
<td class="success">0.001s</td>
|
||||
<td class="success">passed</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="success">findByCustomerId_ShouldReturnCustomerOrders()</td>
|
||||
<td class="success">0.002s</td>
|
||||
<td class="success">passed</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="success">findById_WhenOrderExists_ShouldReturnOrder()</td>
|
||||
<td class="success">0.001s</td>
|
||||
<td class="success">passed</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="success">findByStatus_ShouldReturnOrdersByStatus()</td>
|
||||
<td class="success">0.002s</td>
|
||||
<td class="success">passed</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="success">update_WhenOrderExists_ShouldUpdateOrder()</td>
|
||||
<td class="success">0.002s</td>
|
||||
<td class="success">passed</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div id="footer">
|
||||
<p>
|
||||
<div>
|
||||
<label class="hidden" id="label-for-line-wrapping-toggle" for="line-wrapping-toggle">Wrap lines
|
||||
<input id="line-wrapping-toggle" type="checkbox" autocomplete="off"/>
|
||||
</label>
|
||||
</div>Generated by
|
||||
<a href="https://www.gradle.org">Gradle 8.14.3</a> at 13 дек. 2025 г., 19:44:16</p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
174
build/reports/tests/test/css/base-style.css
Normal file
174
build/reports/tests/test/css/base-style.css
Normal file
@@ -0,0 +1,174 @@
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: sans-serif;
|
||||
font-size: 12pt;
|
||||
}
|
||||
|
||||
body, a, a:visited {
|
||||
color: #303030;
|
||||
}
|
||||
|
||||
#content {
|
||||
padding: 30px 50px;
|
||||
}
|
||||
|
||||
#content h1 {
|
||||
font-size: 160%;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
#footer {
|
||||
margin-top: 100px;
|
||||
font-size: 80%;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
#footer, #footer a {
|
||||
color: #a0a0a0;
|
||||
}
|
||||
|
||||
#line-wrapping-toggle {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
#label-for-line-wrapping-toggle {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
ul {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
h1, h2, h3 {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 120%;
|
||||
}
|
||||
|
||||
.tab-container .tab-container {
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
ul.tabLinks {
|
||||
padding: 0;
|
||||
margin-bottom: 0;
|
||||
overflow: auto;
|
||||
min-width: 800px;
|
||||
width: auto;
|
||||
border-bottom: solid 1px #aaa;
|
||||
}
|
||||
|
||||
ul.tabLinks li {
|
||||
float: left;
|
||||
height: 100%;
|
||||
list-style: none;
|
||||
padding: 5px 10px;
|
||||
border-radius: 7px 7px 0 0;
|
||||
border: solid 1px transparent;
|
||||
border-bottom: none;
|
||||
margin-right: 6px;
|
||||
background-color: #f0f0f0;
|
||||
}
|
||||
|
||||
ul.tabLinks li.deselected > a {
|
||||
color: #6d6d6d;
|
||||
}
|
||||
|
||||
ul.tabLinks li:hover {
|
||||
background-color: #fafafa;
|
||||
}
|
||||
|
||||
ul.tabLinks li.selected {
|
||||
background-color: #c5f0f5;
|
||||
border-color: #aaa;
|
||||
}
|
||||
|
||||
ul.tabLinks a {
|
||||
font-size: 120%;
|
||||
display: block;
|
||||
outline: none;
|
||||
text-decoration: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
ul.tabLinks li h2 {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
div.tab {
|
||||
}
|
||||
|
||||
div.selected {
|
||||
display: block;
|
||||
}
|
||||
|
||||
div.deselected {
|
||||
display: none;
|
||||
}
|
||||
|
||||
div.tab table {
|
||||
min-width: 350px;
|
||||
width: auto;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
div.tab th, div.tab table {
|
||||
border-bottom: solid 1px #d0d0d0;
|
||||
}
|
||||
|
||||
div.tab th {
|
||||
text-align: left;
|
||||
white-space: nowrap;
|
||||
padding-left: 6em;
|
||||
}
|
||||
|
||||
div.tab th:first-child {
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
div.tab td {
|
||||
white-space: nowrap;
|
||||
padding-left: 6em;
|
||||
padding-top: 5px;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
|
||||
div.tab td:first-child {
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
div.tab td.numeric, div.tab th.numeric {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
span.code {
|
||||
display: inline-block;
|
||||
margin-top: 0;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
span.code pre {
|
||||
font-size: 11pt;
|
||||
padding: 10px;
|
||||
margin: 0;
|
||||
background-color: #f7f7f7;
|
||||
border: solid 1px #d0d0d0;
|
||||
min-width: 700px;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
span.wrapped pre {
|
||||
word-wrap: break-word;
|
||||
white-space: pre-wrap;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
label.hidden {
|
||||
display: none;
|
||||
}
|
||||
84
build/reports/tests/test/css/style.css
Normal file
84
build/reports/tests/test/css/style.css
Normal file
@@ -0,0 +1,84 @@
|
||||
|
||||
#summary {
|
||||
margin-top: 30px;
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
#summary table {
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
#summary td {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.breadcrumbs, .breadcrumbs a {
|
||||
color: #606060;
|
||||
}
|
||||
|
||||
.infoBox {
|
||||
width: 110px;
|
||||
padding-top: 15px;
|
||||
padding-bottom: 15px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.infoBox p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.counter, .percent {
|
||||
font-size: 120%;
|
||||
font-weight: bold;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
#duration {
|
||||
width: 125px;
|
||||
}
|
||||
|
||||
#successRate, .summaryGroup {
|
||||
border: solid 2px #d0d0d0;
|
||||
-moz-border-radius: 10px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
#successRate {
|
||||
width: 140px;
|
||||
margin-left: 35px;
|
||||
}
|
||||
|
||||
#successRate .percent {
|
||||
font-size: 180%;
|
||||
}
|
||||
|
||||
.success, .success a {
|
||||
color: #008000;
|
||||
}
|
||||
|
||||
div.success, #successRate.success {
|
||||
background-color: #bbd9bb;
|
||||
border-color: #008000;
|
||||
}
|
||||
|
||||
.failures, .failures a {
|
||||
color: #b60808;
|
||||
}
|
||||
|
||||
.skipped, .skipped a {
|
||||
color: #c09853;
|
||||
}
|
||||
|
||||
div.failures, #successRate.failures {
|
||||
background-color: #ecdada;
|
||||
border-color: #b60808;
|
||||
}
|
||||
|
||||
ul.linkList {
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
ul.linkList li {
|
||||
list-style: none;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
153
build/reports/tests/test/index.html
Normal file
153
build/reports/tests/test/index.html
Normal file
@@ -0,0 +1,153 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
||||
<meta http-equiv="x-ua-compatible" content="IE=edge"/>
|
||||
<title>Test results - Test Summary</title>
|
||||
<link href="css/base-style.css" rel="stylesheet" type="text/css"/>
|
||||
<link href="css/style.css" rel="stylesheet" type="text/css"/>
|
||||
<script src="js/report.js" type="text/javascript"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="content">
|
||||
<h1>Test Summary</h1>
|
||||
<div id="summary">
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<div class="summaryGroup">
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<div class="infoBox" id="tests">
|
||||
<div class="counter">17</div>
|
||||
<p>tests</p>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="infoBox" id="failures">
|
||||
<div class="counter">0</div>
|
||||
<p>failures</p>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="infoBox" id="ignored">
|
||||
<div class="counter">0</div>
|
||||
<p>ignored</p>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="infoBox" id="duration">
|
||||
<div class="counter">0.663s</div>
|
||||
<p>duration</p>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="infoBox success" id="successRate">
|
||||
<div class="percent">100%</div>
|
||||
<p>successful</p>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="tab-container">
|
||||
<ul class="tabLinks">
|
||||
<li>
|
||||
<a href="#">Packages</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#">Classes</a>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="tab">
|
||||
<h2>Packages</h2>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Package</th>
|
||||
<th>Tests</th>
|
||||
<th>Failures</th>
|
||||
<th>Ignored</th>
|
||||
<th>Duration</th>
|
||||
<th>Success rate</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="success">
|
||||
<a href="packages/com.example.service.html">com.example.service</a>
|
||||
</td>
|
||||
<td>17</td>
|
||||
<td>0</td>
|
||||
<td>0</td>
|
||||
<td>0.663s</td>
|
||||
<td class="success">100%</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="tab">
|
||||
<h2>Classes</h2>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Class</th>
|
||||
<th>Tests</th>
|
||||
<th>Failures</th>
|
||||
<th>Ignored</th>
|
||||
<th>Duration</th>
|
||||
<th>Success rate</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="success">
|
||||
<a href="classes/com.example.service.CustomerServiceTest.html">com.example.service.CustomerServiceTest</a>
|
||||
</td>
|
||||
<td>2</td>
|
||||
<td>0</td>
|
||||
<td>0</td>
|
||||
<td>0.559s</td>
|
||||
<td class="success">100%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="success">
|
||||
<a href="classes/com.example.service.DeliveryServiceTest.html">com.example.service.DeliveryServiceTest</a>
|
||||
</td>
|
||||
<td>6</td>
|
||||
<td>0</td>
|
||||
<td>0</td>
|
||||
<td>0.051s</td>
|
||||
<td class="success">100%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="success">
|
||||
<a href="classes/com.example.service.OrderServiceTest.html">com.example.service.OrderServiceTest</a>
|
||||
</td>
|
||||
<td>9</td>
|
||||
<td>0</td>
|
||||
<td>0</td>
|
||||
<td>0.053s</td>
|
||||
<td class="success">100%</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div id="footer">
|
||||
<p>
|
||||
<div>
|
||||
<label class="hidden" id="label-for-line-wrapping-toggle" for="line-wrapping-toggle">Wrap lines
|
||||
<input id="line-wrapping-toggle" type="checkbox" autocomplete="off"/>
|
||||
</label>
|
||||
</div>Generated by
|
||||
<a href="https://www.gradle.org">Gradle 8.14.3</a> at 13 дек. 2025 г., 19:44:16</p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
218
build/reports/tests/test/js/report.js
Normal file
218
build/reports/tests/test/js/report.js
Normal file
@@ -0,0 +1,218 @@
|
||||
(function (window, document) {
|
||||
"use strict";
|
||||
|
||||
function changeElementClass(element, classValue) {
|
||||
if (element.getAttribute("className")) {
|
||||
element.setAttribute("className", classValue);
|
||||
} else {
|
||||
element.setAttribute("class", classValue);
|
||||
}
|
||||
}
|
||||
|
||||
function getClassAttribute(element) {
|
||||
if (element.getAttribute("className")) {
|
||||
return element.getAttribute("className");
|
||||
} else {
|
||||
return element.getAttribute("class");
|
||||
}
|
||||
}
|
||||
|
||||
function addClass(element, classValue) {
|
||||
changeElementClass(element, getClassAttribute(element) + " " + classValue);
|
||||
}
|
||||
|
||||
function removeClass(element, classValue) {
|
||||
changeElementClass(element, getClassAttribute(element).replace(classValue, ""));
|
||||
}
|
||||
|
||||
function getCheckBox() {
|
||||
return document.getElementById("line-wrapping-toggle");
|
||||
}
|
||||
|
||||
function getLabelForCheckBox() {
|
||||
return document.getElementById("label-for-line-wrapping-toggle");
|
||||
}
|
||||
|
||||
function findCodeBlocks() {
|
||||
const codeBlocks = [];
|
||||
const tabContainers = getTabContainers();
|
||||
for (let i = 0; i < tabContainers.length; i++) {
|
||||
const spans = tabContainers[i].getElementsByTagName("span");
|
||||
for (let i = 0; i < spans.length; ++i) {
|
||||
if (spans[i].className.indexOf("code") >= 0) {
|
||||
codeBlocks.push(spans[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return codeBlocks;
|
||||
}
|
||||
|
||||
function forAllCodeBlocks(operation) {
|
||||
const codeBlocks = findCodeBlocks();
|
||||
|
||||
for (let i = 0; i < codeBlocks.length; ++i) {
|
||||
operation(codeBlocks[i], "wrapped");
|
||||
}
|
||||
}
|
||||
|
||||
function toggleLineWrapping() {
|
||||
const checkBox = getCheckBox();
|
||||
|
||||
if (checkBox.checked) {
|
||||
forAllCodeBlocks(addClass);
|
||||
} else {
|
||||
forAllCodeBlocks(removeClass);
|
||||
}
|
||||
}
|
||||
|
||||
function initControls() {
|
||||
if (findCodeBlocks().length > 0) {
|
||||
const checkBox = getCheckBox();
|
||||
const label = getLabelForCheckBox();
|
||||
|
||||
checkBox.onclick = toggleLineWrapping;
|
||||
checkBox.checked = false;
|
||||
|
||||
removeClass(label, "hidden");
|
||||
}
|
||||
}
|
||||
|
||||
class TabManager {
|
||||
baseId;
|
||||
tabs;
|
||||
titles;
|
||||
headers;
|
||||
|
||||
constructor(baseId, tabs, titles, headers) {
|
||||
this.baseId = baseId;
|
||||
this.tabs = tabs;
|
||||
this.titles = titles;
|
||||
this.headers = headers;
|
||||
}
|
||||
|
||||
select(i) {
|
||||
this.deselectAll();
|
||||
|
||||
changeElementClass(this.tabs[i], "tab selected");
|
||||
changeElementClass(this.headers[i], "selected");
|
||||
|
||||
while (this.headers[i].firstChild) {
|
||||
this.headers[i].removeChild(this.headers[i].firstChild);
|
||||
}
|
||||
|
||||
const a = document.createElement("a");
|
||||
|
||||
a.appendChild(document.createTextNode(this.titles[i]));
|
||||
this.headers[i].appendChild(a);
|
||||
}
|
||||
|
||||
deselectAll() {
|
||||
for (let i = 0; i < this.tabs.length; i++) {
|
||||
changeElementClass(this.tabs[i], "tab deselected");
|
||||
changeElementClass(this.headers[i], "deselected");
|
||||
|
||||
while (this.headers[i].firstChild) {
|
||||
this.headers[i].removeChild(this.headers[i].firstChild);
|
||||
}
|
||||
|
||||
const a = document.createElement("a");
|
||||
|
||||
const id = this.baseId + "-tab" + i;
|
||||
a.setAttribute("id", id);
|
||||
a.setAttribute("href", "#tab" + i);
|
||||
a.onclick = () => {
|
||||
this.select(i);
|
||||
return false;
|
||||
};
|
||||
a.appendChild(document.createTextNode(this.titles[i]));
|
||||
|
||||
this.headers[i].appendChild(a);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getTabContainers() {
|
||||
const tabContainers = Array.from(document.getElementsByClassName("tab-container"));
|
||||
|
||||
// Used by existing TabbedPageRenderer users, which have not adjusted to use TabsRenderer yet.
|
||||
const legacyContainer = document.getElementById("tabs");
|
||||
if (legacyContainer) {
|
||||
tabContainers.push(legacyContainer);
|
||||
}
|
||||
|
||||
return tabContainers;
|
||||
}
|
||||
|
||||
function initTabs() {
|
||||
let tabGroups = 0;
|
||||
|
||||
function createTab(num, container) {
|
||||
const tabElems = findTabs(container);
|
||||
const tabManager = new TabManager("tabs" + num, tabElems, findTitles(tabElems), findHeaders(container));
|
||||
tabManager.select(0);
|
||||
}
|
||||
|
||||
const tabContainers = getTabContainers();
|
||||
|
||||
for (let i = 0; i < tabContainers.length; i++) {
|
||||
createTab(tabGroups, tabContainers[i]);
|
||||
tabGroups++;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function findTabs(container) {
|
||||
return findChildElements(container, "DIV", "tab");
|
||||
}
|
||||
|
||||
function findHeaders(container) {
|
||||
const owner = findChildElements(container, "UL", "tabLinks");
|
||||
return findChildElements(owner[0], "LI", null);
|
||||
}
|
||||
|
||||
function findTitles(tabs) {
|
||||
const titles = [];
|
||||
|
||||
for (let i = 0; i < tabs.length; i++) {
|
||||
const tab = tabs[i];
|
||||
const header = findChildElements(tab, "H2", null)[0];
|
||||
|
||||
header.parentNode.removeChild(header);
|
||||
|
||||
if (header.innerText) {
|
||||
titles.push(header.innerText);
|
||||
} else {
|
||||
titles.push(header.textContent);
|
||||
}
|
||||
}
|
||||
|
||||
return titles;
|
||||
}
|
||||
|
||||
function findChildElements(container, name, targetClass) {
|
||||
const elements = [];
|
||||
const children = container.childNodes;
|
||||
|
||||
for (let i = 0; i < children.length; i++) {
|
||||
const child = children.item(i);
|
||||
|
||||
if (child.nodeType === 1 && child.nodeName === name) {
|
||||
if (targetClass && child.className.indexOf(targetClass) < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
elements.push(child);
|
||||
}
|
||||
}
|
||||
|
||||
return elements;
|
||||
}
|
||||
|
||||
// Entry point.
|
||||
|
||||
window.onload = function() {
|
||||
initTabs();
|
||||
initControls();
|
||||
};
|
||||
} (window, window.document));
|
||||
123
build/reports/tests/test/packages/com.example.service.html
Normal file
123
build/reports/tests/test/packages/com.example.service.html
Normal file
@@ -0,0 +1,123 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
||||
<meta http-equiv="x-ua-compatible" content="IE=edge"/>
|
||||
<title>Test results - Package com.example.service</title>
|
||||
<link href="../css/base-style.css" rel="stylesheet" type="text/css"/>
|
||||
<link href="../css/style.css" rel="stylesheet" type="text/css"/>
|
||||
<script src="../js/report.js" type="text/javascript"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="content">
|
||||
<h1>Package com.example.service</h1>
|
||||
<div class="breadcrumbs">
|
||||
<a href="../index.html">all</a> > com.example.service</div>
|
||||
<div id="summary">
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<div class="summaryGroup">
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<div class="infoBox" id="tests">
|
||||
<div class="counter">17</div>
|
||||
<p>tests</p>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="infoBox" id="failures">
|
||||
<div class="counter">0</div>
|
||||
<p>failures</p>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="infoBox" id="ignored">
|
||||
<div class="counter">0</div>
|
||||
<p>ignored</p>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="infoBox" id="duration">
|
||||
<div class="counter">0.663s</div>
|
||||
<p>duration</p>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="infoBox success" id="successRate">
|
||||
<div class="percent">100%</div>
|
||||
<p>successful</p>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="tab-container">
|
||||
<ul class="tabLinks">
|
||||
<li>
|
||||
<a href="#">Classes</a>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="tab">
|
||||
<h2>Classes</h2>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Class</th>
|
||||
<th>Tests</th>
|
||||
<th>Failures</th>
|
||||
<th>Ignored</th>
|
||||
<th>Duration</th>
|
||||
<th>Success rate</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tr>
|
||||
<td class="success">
|
||||
<a href="../classes/com.example.service.CustomerServiceTest.html">CustomerServiceTest</a>
|
||||
</td>
|
||||
<td>2</td>
|
||||
<td>0</td>
|
||||
<td>0</td>
|
||||
<td>0.559s</td>
|
||||
<td class="success">100%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="success">
|
||||
<a href="../classes/com.example.service.DeliveryServiceTest.html">DeliveryServiceTest</a>
|
||||
</td>
|
||||
<td>6</td>
|
||||
<td>0</td>
|
||||
<td>0</td>
|
||||
<td>0.051s</td>
|
||||
<td class="success">100%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="success">
|
||||
<a href="../classes/com.example.service.OrderServiceTest.html">OrderServiceTest</a>
|
||||
</td>
|
||||
<td>9</td>
|
||||
<td>0</td>
|
||||
<td>0</td>
|
||||
<td>0.053s</td>
|
||||
<td class="success">100%</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div id="footer">
|
||||
<p>
|
||||
<div>
|
||||
<label class="hidden" id="label-for-line-wrapping-toggle" for="line-wrapping-toggle">Wrap lines
|
||||
<input id="line-wrapping-toggle" type="checkbox" autocomplete="off"/>
|
||||
</label>
|
||||
</div>Generated by
|
||||
<a href="https://www.gradle.org">Gradle 8.14.3</a> at 13 дек. 2025 г., 19:44:16</p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,5 +1,5 @@
|
||||
build.artifact=demo
|
||||
build.group=com.example
|
||||
build.name=demo
|
||||
build.time=2025-12-12T19\:06\:15.909391Z
|
||||
build.time=2025-12-13T16\:00\:42.386508Z
|
||||
build.version=0.0.1-SNAPSHOT
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
|
||||
INSERT INTO customers (id, name, email, created_at, updated_at)
|
||||
VALUES
|
||||
(1, 'Иван Иванов', 'ivan@mail.ru', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
|
||||
(2, 'Петр Петров', 'petr@mail.ru', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
|
||||
(3, 'Мария Сидорова', 'maria@mail.ru', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
|
||||
(4, 'Алексей Козлов', 'alex@mail.ru', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
|
||||
(5, 'Ольга Новикова', 'olga@mail.ru', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
|
||||
|
||||
INSERT INTO deliveries (id, tracking_number, destination, status, customer_name, created_at, updated_at)
|
||||
VALUES
|
||||
(1, 'IVN777777', 'гоголя 34', 'В пути', 'Иван Иванов', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
|
||||
(2, 'IVN012021', 'Москва', 'Принято', 'Петр Петров', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
|
||||
File diff suppressed because one or more lines are too long
51
build/resources/main/static/assets/index-DZoZELOR.js
Normal file
51
build/resources/main/static/assets/index-DZoZELOR.js
Normal file
File diff suppressed because one or more lines are too long
@@ -5,7 +5,7 @@
|
||||
<link rel="icon" type="image/svg+xml" href="/assets/react.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Delivery Management System</title>
|
||||
<script type="module" crossorigin src="./assets/index-B-zXX4YT.js"></script>
|
||||
<script type="module" crossorigin src="./assets/index-DZoZELOR.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="./assets/index-BWtOf8p2.css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<testsuite name="com.example.service.CustomerServiceTest" tests="2" skipped="0" failures="0" errors="0" timestamp="2025-12-13T15:44:16.086Z" hostname="MacBook-Air-Oleg.local" time="0.561">
|
||||
<properties/>
|
||||
<testcase name="create_WhenValidData_ShouldCreateCustomer()" classname="com.example.service.CustomerServiceTest" time="0.556"/>
|
||||
<testcase name="findById_WhenCustomerExists_ShouldReturnCustomer()" classname="com.example.service.CustomerServiceTest" time="0.003"/>
|
||||
<system-out><![CDATA[]]></system-out>
|
||||
<system-err><![CDATA[Mockito is currently self-attaching to enable the inline-mock-maker. This will no longer work in future releases of the JDK. Please add Mockito as an agent to your build as described in Mockito's documentation: https://javadoc.io/doc/org.mockito/mockito-core/latest/org.mockito/org/mockito/Mockito.html#0.3
|
||||
WARNING: A Java agent has been loaded dynamically (/Users/floom/.gradle/caches/modules-2/files-2.1/net.bytebuddy/byte-buddy-agent/1.17.7/fbf3d6d649ed37fc9e9c59480a05be0a26e3c2da/byte-buddy-agent-1.17.7.jar)
|
||||
WARNING: If a serviceability tool is in use, please run with -XX:+EnableDynamicAgentLoading to hide this warning
|
||||
WARNING: If a serviceability tool is not in use, please run with -Djdk.instrument.traceUsage for more information
|
||||
WARNING: Dynamic loading of agents will be disallowed by default in a future release
|
||||
]]></system-err>
|
||||
</testsuite>
|
||||
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<testsuite name="com.example.service.DeliveryServiceTest" tests="6" skipped="0" failures="0" errors="0" timestamp="2025-12-13T15:44:16.650Z" hostname="MacBook-Air-Oleg.local" time="0.051">
|
||||
<properties/>
|
||||
<testcase name="findById_WhenDeliveryExists_ShouldReturnDelivery()" classname="com.example.service.DeliveryServiceTest" time="0.042"/>
|
||||
<testcase name="create_WhenValidData_ShouldCreateDelivery()" classname="com.example.service.DeliveryServiceTest" time="0.002"/>
|
||||
<testcase name="delete_WhenDeliveryNotExists_ShouldReturnFalse()" classname="com.example.service.DeliveryServiceTest" time="0.002"/>
|
||||
<testcase name="update_WhenDeliveryExists_ShouldUpdateDelivery()" classname="com.example.service.DeliveryServiceTest" time="0.002"/>
|
||||
<testcase name="delete_WhenDeliveryExists_ShouldDeleteDelivery()" classname="com.example.service.DeliveryServiceTest" time="0.001"/>
|
||||
<testcase name="findAll_ShouldReturnAllDeliveries()" classname="com.example.service.DeliveryServiceTest" time="0.002"/>
|
||||
<system-out><![CDATA[]]></system-out>
|
||||
<system-err><![CDATA[]]></system-err>
|
||||
</testsuite>
|
||||
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<testsuite name="com.example.service.OrderServiceTest" tests="9" skipped="0" failures="0" errors="0" timestamp="2025-12-13T15:44:16.702Z" hostname="MacBook-Air-Oleg.local" time="0.055">
|
||||
<properties/>
|
||||
<testcase name="create_WhenValidData_ShouldCreateOrder()" classname="com.example.service.OrderServiceTest" time="0.041"/>
|
||||
<testcase name="findByCustomerId_ShouldReturnCustomerOrders()" classname="com.example.service.OrderServiceTest" time="0.002"/>
|
||||
<testcase name="create_WhenCustomerNotFound_ShouldThrowException()" classname="com.example.service.OrderServiceTest" time="0.002"/>
|
||||
<testcase name="findById_WhenOrderExists_ShouldReturnOrder()" classname="com.example.service.OrderServiceTest" time="0.001"/>
|
||||
<testcase name="findAll_ShouldReturnAllOrders()" classname="com.example.service.OrderServiceTest" time="0.001"/>
|
||||
<testcase name="delete_WhenOrderNotExists_ShouldReturnFalse()" classname="com.example.service.OrderServiceTest" time="0.001"/>
|
||||
<testcase name="findByStatus_ShouldReturnOrdersByStatus()" classname="com.example.service.OrderServiceTest" time="0.002"/>
|
||||
<testcase name="delete_WhenOrderExists_ShouldDeleteOrder()" classname="com.example.service.OrderServiceTest" time="0.001"/>
|
||||
<testcase name="update_WhenOrderExists_ShouldUpdateOrder()" classname="com.example.service.OrderServiceTest" time="0.002"/>
|
||||
<system-out><![CDATA[]]></system-out>
|
||||
<system-err><![CDATA[]]></system-err>
|
||||
</testsuite>
|
||||
BIN
build/test-results/test/binary/output.bin
Normal file
BIN
build/test-results/test/binary/output.bin
Normal file
Binary file not shown.
BIN
build/test-results/test/binary/output.bin.idx
Normal file
BIN
build/test-results/test/binary/output.bin.idx
Normal file
Binary file not shown.
BIN
build/test-results/test/binary/results.bin
Normal file
BIN
build/test-results/test/binary/results.bin
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
build/tmp/compileTestJava/previous-compilation-data.bin
Normal file
BIN
build/tmp/compileTestJava/previous-compilation-data.bin
Normal file
Binary file not shown.
4
build/tmp/jar/MANIFEST.MF
Normal file
4
build/tmp/jar/MANIFEST.MF
Normal file
@@ -0,0 +1,4 @@
|
||||
Manifest-Version: 1.0
|
||||
Main-Class: com.example.DemoApplication
|
||||
Start-Class: com.example.DemoApplication
|
||||
|
||||
BIN
data.mv.db
BIN
data.mv.db
Binary file not shown.
@@ -65,3 +65,11 @@ Caused by: org.h2.mvstore.MVStoreException: The file is locked: /Users/floom/PIb
|
||||
at org.h2.mvstore.SingleFileStore.open(SingleFileStore.java:81)
|
||||
at org.h2.mvstore.MVStore.<init>(MVStore.java:286)
|
||||
... 42 more
|
||||
2025-12-13 03:59:21.102824+04:00 jdbc[13]: exception
|
||||
org.h2.jdbc.JdbcSQLSyntaxErrorException: Синтаксическая ошибка в выражении SQL "SELECT * FROM ORDERS DELIVERIES [*]CUSTOMERS PRODUCTS"
|
||||
Syntax error in SQL statement "SELECT * FROM ORDERS DELIVERIES [*]CUSTOMERS PRODUCTS"; SQL statement:
|
||||
SELECT * FROM ORDERS DELIVERIES CUSTOMERS PRODUCTS [42000-232]
|
||||
2025-12-13 03:59:33.309067+04:00 jdbc[13]: exception
|
||||
org.h2.jdbc.JdbcSQLSyntaxErrorException: Синтаксическая ошибка в выражении SQL "SELECT * FROM ORDERS DELIVERIES [*]CUSTOMERS PRODUCTS ORDERS DELIVERIES"
|
||||
Syntax error in SQL statement "SELECT * FROM ORDERS DELIVERIES [*]CUSTOMERS PRODUCTS ORDERS DELIVERIES"; SQL statement:
|
||||
SELECT * FROM ORDERS DELIVERIES CUSTOMERS PRODUCTS ORDERS DELIVERIES [42000-232]
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// front/src/components/OrderList.jsx
|
||||
import { useState, useEffect } from 'react';
|
||||
import OrderItem from './OrderItem';
|
||||
import OrderFilter from './OrderFilter';
|
||||
@@ -12,9 +13,11 @@ function OrderList() {
|
||||
const [deliveries, setDeliveries] = useState([]);
|
||||
const [filteredOrders, setFilteredOrders] = useState([]);
|
||||
const [editingOrder, setEditingOrder] = useState(null);
|
||||
const [itemsPerPage, setItemsPerPage] = useState(5); // состояние для подсчета элементов
|
||||
|
||||
useEffect(() => {
|
||||
loadCustomersAndDeliveries();
|
||||
loadOrders(0, itemsPerPage); // itemsPerPage
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -77,8 +80,7 @@ function OrderList() {
|
||||
throw new Error(errorText || `HTTP error! status: ${response.status}`);
|
||||
}
|
||||
|
||||
// Перезагружаем данные с текущей страницы
|
||||
await loadOrders(pagination.page, pagination.size);
|
||||
await loadOrders(pagination.page, itemsPerPage); // itemsPerPage
|
||||
setEditingOrder(null);
|
||||
} catch (error) {
|
||||
console.error('Ошибка создания заказа:', error);
|
||||
@@ -109,7 +111,7 @@ function OrderList() {
|
||||
throw new Error(errorText || `HTTP error! status: ${response.status}`);
|
||||
}
|
||||
|
||||
await loadOrders(pagination.page, pagination.size);
|
||||
await loadOrders(pagination.page, itemsPerPage); // itemsPerPage
|
||||
setEditingOrder(null);
|
||||
} catch (error) {
|
||||
console.error('Ошибка обновления заказа:', error);
|
||||
@@ -128,7 +130,7 @@ function OrderList() {
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
}
|
||||
|
||||
await loadOrders(pagination.page, pagination.size);
|
||||
await loadOrders(pagination.page, itemsPerPage); // itemsPerPage
|
||||
} catch (error) {
|
||||
console.error('Ошибка удаления заказа:', error);
|
||||
alert('Ошибка при удалении заказа: ' + error.message);
|
||||
@@ -145,7 +147,14 @@ function OrderList() {
|
||||
};
|
||||
|
||||
const handlePageChange = (newPage) => {
|
||||
loadOrders(newPage, pagination.size);
|
||||
loadOrders(newPage, itemsPerPage); // itemsPerPage
|
||||
};
|
||||
|
||||
// ФУНКЦИЯ ДЛЯ ДОПКИ
|
||||
const handleItemsPerPageChange = (e) => {
|
||||
const newSize = parseInt(e.target.value);
|
||||
setItemsPerPage(newSize);
|
||||
loadOrders(0, newSize);
|
||||
};
|
||||
|
||||
if (loading && orders.length === 0) {
|
||||
@@ -153,8 +162,12 @@ function OrderList() {
|
||||
}
|
||||
|
||||
return (
|
||||
<div style={{ maxWidth: '1200px', margin: '0 auto' }}>
|
||||
<h2>Управление заказами</h2>
|
||||
<div style={{
|
||||
maxWidth: '1200px',
|
||||
margin: '0 auto',
|
||||
padding: '20px'
|
||||
}}>
|
||||
<h2 style={{ color: '#6aa1d1' }}>Управление заказами</h2>
|
||||
|
||||
<OrderStats orders={orders} />
|
||||
|
||||
@@ -167,11 +180,52 @@ function OrderList() {
|
||||
|
||||
<OrderFilter onFilterChange={handleFilterChange} />
|
||||
|
||||
<div>
|
||||
<h3>
|
||||
Список заказов ({pagination.totalElements})
|
||||
{pagination.totalPages > 1 && ` - Страница ${pagination.page + 1} из ${pagination.totalPages}`}
|
||||
</h3>
|
||||
<div style={{ marginTop: '30px' }}>
|
||||
<div style={{
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
marginBottom: '20px',
|
||||
flexWrap: 'wrap',
|
||||
gap: '10px'
|
||||
}}>
|
||||
<h3 style={{ margin: 0, color: '#6aa1d1' }}>
|
||||
Список заказов ({pagination.totalElements})
|
||||
{pagination.totalPages > 1 && ` - Страница ${pagination.page + 1} из ${pagination.totalPages}`}
|
||||
</h3>
|
||||
|
||||
{/* Список с выбором кол-ва записей */}
|
||||
<div style={{
|
||||
color: '#666',
|
||||
fontSize: '14px',
|
||||
padding: '5px 10px',
|
||||
backgroundColor: '#f5f5f5',
|
||||
borderRadius: '4px',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: '5px'
|
||||
}}>
|
||||
<span>Показывается по</span>
|
||||
<select
|
||||
value={itemsPerPage}
|
||||
onChange={handleItemsPerPageChange}
|
||||
style={{
|
||||
padding: '3px 8px',
|
||||
border: '1px solid #ddd',
|
||||
borderRadius: '4px',
|
||||
backgroundColor: 'black',
|
||||
cursor: 'pointer'
|
||||
}}
|
||||
>
|
||||
<option value="5">5</option>
|
||||
<option value="10">10</option>
|
||||
<option value="15">15</option>
|
||||
<option value="20">20</option>
|
||||
<option value="25">25</option>
|
||||
</select>
|
||||
<span>заказов на странице</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Пагинация сверху */}
|
||||
<Pagination
|
||||
@@ -180,16 +234,35 @@ function OrderList() {
|
||||
/>
|
||||
|
||||
{filteredOrders.length === 0 ? (
|
||||
<p>Заказы не найдены</p>
|
||||
<p style={{
|
||||
textAlign: 'center',
|
||||
padding: '40px',
|
||||
color: '#666',
|
||||
fontSize: '18px',
|
||||
backgroundColor: '#f9f9f9',
|
||||
borderRadius: '8px'
|
||||
}}>
|
||||
Заказы не найдены
|
||||
</p>
|
||||
) : (
|
||||
filteredOrders.map(order => (
|
||||
<OrderItem
|
||||
key={order.id}
|
||||
order={order}
|
||||
onEdit={setEditingOrder}
|
||||
onDelete={handleDeleteOrder}
|
||||
/>
|
||||
))
|
||||
<div style={{
|
||||
display: 'grid',
|
||||
gridTemplateColumns: 'repeat(auto-fill, minmax(350px, 1fr))',
|
||||
gap: '20px',
|
||||
margin: '20px 0'
|
||||
}}>
|
||||
{filteredOrders.map(order => (
|
||||
<div key={order.id} style={{
|
||||
transition: 'transform 0.2s ease'
|
||||
}}>
|
||||
<OrderItem
|
||||
order={order}
|
||||
onEdit={setEditingOrder}
|
||||
onDelete={handleDeleteOrder}
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Пагинация снизу */}
|
||||
|
||||
@@ -6,12 +6,12 @@ export const useOrders = () => {
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [pagination, setPagination] = useState({
|
||||
page: 0,
|
||||
size: 10,
|
||||
size: 5,
|
||||
totalPages: 0,
|
||||
totalElements: 0
|
||||
});
|
||||
|
||||
const loadOrders = async (page = 0, size = 10) => {
|
||||
const loadOrders = async (page = 0, size = 5) => {
|
||||
setLoading(true);
|
||||
try {
|
||||
const response = await fetch(`http://localhost:8080/api/orders/paginated?page=${page}&size=${size}`);
|
||||
|
||||
19
src/main/java/com/example/controller/DevHomeController.java
Normal file
19
src/main/java/com/example/controller/DevHomeController.java
Normal file
@@ -0,0 +1,19 @@
|
||||
package com.example.controller;
|
||||
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@Controller
|
||||
@ConditionalOnProperty(name = "spring.profiles.active", havingValue = "dev", matchIfMissing = false)
|
||||
public class DevHomeController {
|
||||
|
||||
@GetMapping("/")
|
||||
public void home(HttpServletResponse response) throws IOException {
|
||||
// Просто перенаправляем на H2 Console
|
||||
response.sendRedirect("");
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,45 @@
|
||||
package com.example.controller;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.servlet.HandlerMapping;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@Controller
|
||||
@ConditionalOnProperty(name = "spring.profiles.active", havingValue = "front", matchIfMissing = false)
|
||||
public class SpaController {
|
||||
@RequestMapping(value = {"/", "/orders", "/deliveries", "/customers", "/stats"})
|
||||
public String redirectToIndex() {
|
||||
return "forward:/index.html";
|
||||
|
||||
@GetMapping("/**")
|
||||
public ResponseEntity<Resource> forwardToIndex(HttpServletRequest request) throws IOException {
|
||||
String path = request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE).toString();
|
||||
|
||||
if (path.startsWith("/api") ||
|
||||
path.startsWith("/h2-console") ||
|
||||
path.startsWith("/swagger-ui") ||
|
||||
path.startsWith("/v3") ||
|
||||
path.startsWith("/actuator") ||
|
||||
path.equals("/error") ||
|
||||
path.contains(".")) {
|
||||
return ResponseEntity.notFound().build();
|
||||
}
|
||||
|
||||
Resource resource = new ClassPathResource("static" + path);
|
||||
if (resource.exists()) {
|
||||
return ResponseEntity.ok(resource);
|
||||
}
|
||||
|
||||
Resource index = new ClassPathResource("static/index.html");
|
||||
if (index.exists()) {
|
||||
return ResponseEntity.ok(index);
|
||||
}
|
||||
|
||||
return ResponseEntity.notFound().build();
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
|
||||
INSERT INTO customers (id, name, email, created_at, updated_at)
|
||||
VALUES
|
||||
(1, 'Иван Иванов', 'ivan@mail.ru', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
|
||||
(2, 'Петр Петров', 'petr@mail.ru', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
|
||||
(3, 'Мария Сидорова', 'maria@mail.ru', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
|
||||
(4, 'Алексей Козлов', 'alex@mail.ru', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
|
||||
(5, 'Ольга Новикова', 'olga@mail.ru', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
|
||||
|
||||
INSERT INTO deliveries (id, tracking_number, destination, status, customer_name, created_at, updated_at)
|
||||
VALUES
|
||||
(1, 'IVN777777', 'гоголя 34', 'В пути', 'Иван Иванов', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
|
||||
(2, 'IVN012021', 'Москва', 'Принято', 'Петр Петров', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
|
||||
File diff suppressed because one or more lines are too long
51
src/main/resources/static/assets/index-DZoZELOR.js
Normal file
51
src/main/resources/static/assets/index-DZoZELOR.js
Normal file
File diff suppressed because one or more lines are too long
@@ -5,7 +5,7 @@
|
||||
<link rel="icon" type="image/svg+xml" href="/assets/react.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Delivery Management System</title>
|
||||
<script type="module" crossorigin src="./assets/index-B-zXX4YT.js"></script>
|
||||
<script type="module" crossorigin src="./assets/index-DZoZELOR.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="./assets/index-BWtOf8p2.css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
Reference in New Issue
Block a user