Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitc820edd

Browse files
Merge pull request#120 from utPLSQL/feature/issue-110-code-coverage-assets
#110 - Use local assets for code coverage report for offline usage
2 parents7fb1947 +31464af commitc820edd

File tree

31 files changed

+2640
-25
lines changed

31 files changed

+2640
-25
lines changed

‎sqldev/src/main/java/org/utplsql/sqldev/coverage/CodeCoverageReporter.java

Lines changed: 76 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,25 @@
1717

1818
importjava.awt.Desktop;
1919
importjava.io.File;
20+
importjava.io.IOException;
21+
importjava.io.InputStream;
22+
importjava.net.MalformedURLException;
2023
importjava.net.URL;
2124
importjava.nio.charset.StandardCharsets;
25+
importjava.nio.file.Files;
26+
importjava.nio.file.Path;
27+
importjava.nio.file.Paths;
28+
importjava.nio.file.StandardCopyOption;
2229
importjava.sql.Connection;
23-
importjava.util.ArrayList;
24-
importjava.util.Arrays;
25-
importjava.util.HashMap;
26-
importjava.util.List;
27-
importjava.util.Map;
30+
importjava.util.*;
31+
importjava.util.jar.JarEntry;
32+
importjava.util.jar.JarFile;
2833
importjava.util.logging.Logger;
2934
importjava.util.stream.Collectors;
3035

36+
importorg.springframework.core.io.Resource;
37+
importorg.springframework.core.io.support.PathMatchingResourcePatternResolver;
38+
importorg.springframework.core.io.support.ResourcePatternResolver;
3139
importorg.utplsql.sqldev.dal.RealtimeReporterDao;
3240
importorg.utplsql.sqldev.dal.UtplsqlDao;
3341
importorg.utplsql.sqldev.exception.GenericDatabaseAccessException;
@@ -42,22 +50,25 @@
4250

4351
publicclassCodeCoverageReporter {
4452
privatestaticfinalLoggerlogger =Logger.getLogger(CodeCoverageReporter.class.getName());
53+
privatestaticfinalStringASSETS_PATH ="coverage/assets/";
4554

4655
privateStringconnectionName;
4756
privateConnectionconn;
48-
privateList<String>pathList;
49-
privateList<String>includeObjectList;
57+
privatefinalList<String>pathList;
58+
privatefinalList<String>includeObjectList;
5059
privateCodeCoverageReporterDialogframe;
5160
privateStringschemas;
5261
privateStringincludeObjects;
5362
privateStringexcludeObjects;
63+
privatePathassetDir;
5464

5565
publicCodeCoverageReporter(finalList<String>pathList,finalList<String>includeObjectList,
5666
finalStringconnectionName) {
5767
this.pathList =pathList;
5868
this.includeObjectList =includeObjectList;
5969
setDefaultSchema();
6070
setConnection(connectionName);
71+
setAssetDir();
6172
}
6273

6374
// constructor for testing purposes only
@@ -67,6 +78,7 @@ public CodeCoverageReporter(final List<String> pathList, final List<String> incl
6778
this.includeObjectList =includeObjectList;
6879
this.conn =conn;
6980
setDefaultSchema();
81+
setAssetDir();
7082
}
7183

7284
privatevoidsetConnection(finalStringconnectionName) {
@@ -105,6 +117,59 @@ private void setDefaultSchema() {
105117
}
106118
}
107119

120+
privatevoidsetAssetDir() {
121+
try {
122+
assetDir =Files.createTempDirectory("utplsql_assets_");
123+
}catch (IOExceptione) {
124+
thrownewGenericRuntimeException("Cannot create temporary directory for code coverage report assets.",e);
125+
}
126+
populateCoverageAssets();
127+
}
128+
129+
// public for testing purposes only
130+
publicURLgetHtmlReportAssetPath() {
131+
try {
132+
returnPaths.get(assetDir.toString()).toUri().toURL();
133+
}catch (MalformedURLExceptione) {
134+
thrownewGenericRuntimeException("Cannot convert code coverage asset path to URL.",e);
135+
}
136+
}
137+
138+
privatevoidcopyStreamToFile(InputStreaminputStream,Pathfile)throwsIOException {
139+
file.toFile().mkdirs();
140+
Files.copy(inputStream,file,StandardCopyOption.REPLACE_EXISTING);
141+
}
142+
143+
privatevoidpopulateCoverageAssets() {
144+
logger.fine(() ->"Copying code coverage report assets to " +assetDir.toString() +"...");
145+
try {
146+
finalFilefile =newFile(getClass().getProtectionDomain().getCodeSource().getLocation().getPath());
147+
if (file.isFile()) {
148+
// class loaded from a JAR file
149+
finalJarFilejar =newJarFile(file);
150+
finalList<JarEntry>entries =jar.stream().filter(entry -> !entry.isDirectory() &&entry.getName().startsWith(ASSETS_PATH)).collect(Collectors.toList());
151+
for (JarEntryentry :entries) {
152+
Pathf =Paths.get(assetDir.toString() +File.separator +entry.getName().substring(ASSETS_PATH.length()));
153+
copyStreamToFile(jar.getInputStream(entry),f);
154+
}
155+
}else {
156+
// class loaded from file system (IDE or during test/build)
157+
ResourcePatternResolverresolver =newPathMatchingResourcePatternResolver();
158+
Resource[]resources =resolver.getResources(ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +"/" +ASSETS_PATH +"**");
159+
for (Resourceresource :resources) {
160+
if (Objects.requireNonNull(resource.getFilename()).contains(".")) {
161+
// process files but not directories, assume that directories do not contain a period
162+
Stringpath =resource.getURL().getPath();
163+
Pathf =Paths.get(assetDir.toString() +File.separator +path.substring(path.lastIndexOf(ASSETS_PATH) +ASSETS_PATH.length()));
164+
copyStreamToFile(resource.getInputStream(),f);
165+
}
166+
}
167+
}
168+
}catch (IOExceptione) {
169+
thrownewGenericRuntimeException("Error while copying coverage report assets to temporary directory.",e);
170+
}
171+
}
172+
108173
privateArrayList<String>toStringList(finalStrings) {
109174
finalArrayList<String>list =newArrayList<>();
110175
if (s !=null && !s.isEmpty()) {
@@ -142,7 +207,7 @@ private void run() {
142207

143208
privatevoidrunCodeCoverageWithRealtimeReporter() {
144209
finalUtplsqlRunnerrunner =newUtplsqlRunner(pathList,toStringList(schemas),toStringList(includeObjects),
145-
toStringList(excludeObjects),connectionName);
210+
toStringList(excludeObjects),getHtmlReportAssetPath(),connectionName);
146211
runner.runTestAsync();
147212
}
148213

@@ -152,7 +217,7 @@ private void runCodeCoverageStandalone() {
152217
coverageConn =conn !=null ?conn :DatabaseTools.cloneConnection(connectionName);
153218
finalUtplsqlDaodao =newUtplsqlDao(coverageConn);
154219
finalStringhtml =dao.htmlCodeCoverage(pathList,toStringList(schemas),
155-
toStringList(includeObjects),toStringList(excludeObjects));
220+
toStringList(includeObjects),toStringList(excludeObjects),getHtmlReportAssetPath());
156221
openInBrowser(html);
157222
}finally {
158223
try {
@@ -174,7 +239,7 @@ public static void openInBrowser(String html) {
174239
finalURLurl =file.toURI().toURL();
175240
logger.fine(() ->"Opening " +url.toExternalForm() +" in browser...");
176241
finalDesktopdesktop =Desktop.isDesktopSupported() ?Desktop.getDesktop() :null;
177-
if (desktop !=null &&desktop.isSupported(Desktop.Action.BROWSE) &&url !=null) {
242+
if (desktop !=null &&desktop.isSupported(Desktop.Action.BROWSE)) {
178243
desktop.browse(url.toURI());
179244
logger.fine(() ->url.toExternalForm() +" opened in browser.");
180245
}else {
@@ -229,9 +294,7 @@ public void setExcludeObjects(final String excludeObjects) {
229294
}
230295

231296
publicThreadrunAsync() {
232-
finalThreadthread =newThread(() -> {
233-
run();
234-
});
297+
finalThreadthread =newThread(this::run);
235298
thread.setName("code coverage reporter");
236299
thread.start();
237300
returnthread;

‎sqldev/src/main/java/org/utplsql/sqldev/dal/RealtimeReporterDao.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
importjava.io.IOException;
1919
importjava.io.StringReader;
20+
importjava.net.URL;
2021
importjava.sql.Clob;
2122
importjava.sql.Connection;
2223
importjava.sql.ResultSet;
@@ -108,11 +109,11 @@ public void produceReport(final String reporterId, final List<String> pathList)
108109

109110
publicvoidproduceReportWithCoverage(finalStringrealtimeReporterId,finalStringcoverageReporterId,
110111
finalList<String>pathList,finalList<String>schemaList,finalList<String>includeObjectList,
111-
finalList<String>excludeObjectList) {
112+
finalList<String>excludeObjectList,finalURLhtmlReportAssetPath) {
112113
StringBuildersb =newStringBuilder();
113114
sb.append("DECLARE\n");
114115
sb.append(" l_rt_rep ut_realtime_reporter := ut_realtime_reporter();\n");
115-
sb.append(" l_cov_rep ut_coverage_html_reporter := ut_coverage_html_reporter();\n");
116+
sb.append(" l_cov_rep ut_coverage_html_reporter := ut_coverage_html_reporter(a_html_report_assets_path => ?);\n");
116117
sb.append("BEGIN\n");
117118
sb.append(" l_rt_rep.set_reporter_id(?);\n");
118119
sb.append(" l_rt_rep.output_buffer.init();\n");
@@ -143,7 +144,7 @@ public void produceReportWithCoverage(final String realtimeReporterId, final Str
143144
sb.append(" sys.dbms_output.disable;\n");
144145
sb.append("END;");
145146
finalStringplsql =sb.toString();
146-
finalObject[]binds = {realtimeReporterId,coverageReporterId };
147+
finalObject[]binds = {htmlReportAssetPath ==null ?null :htmlReportAssetPath.toExternalForm(),realtimeReporterId,coverageReporterId };
147148
jdbcTemplate.update(plsql,binds);
148149
}
149150

‎sqldev/src/main/java/org/utplsql/sqldev/dal/UtplsqlDao.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616
packageorg.utplsql.sqldev.dal;
1717

18+
importjava.net.URL;
1819
importjava.sql.CallableStatement;
1920
importjava.sql.Connection;
2021
importjava.sql.SQLException;
@@ -907,12 +908,14 @@ public OutputLines doInCallableStatement(final CallableStatement cs) throws SQLE
907908
* @param excludeObjectList
908909
* list of objects to be excluded from coverage analysis. None, if
909910
* empty
911+
* @param htmlReportAssetPath
912+
* path of the assets for the coverage report. Default, if null
910913
* @return HTML code coverage report in HTML format
911914
* @throws DataAccessException
912915
* if there is a problem
913916
*/
914917
publicStringhtmlCodeCoverage(finalList<String>pathList,finalList<String>schemaList,
915-
finalList<String>includeObjectList,finalList<String>excludeObjectList) {
918+
finalList<String>includeObjectList,finalList<String>excludeObjectList,finalURLhtmlReportAssetPath) {
916919
StringBuildersb =newStringBuilder();
917920
sb.append("SELECT column_value\n");
918921
sb.append(" FROM table(\n");
@@ -935,7 +938,14 @@ public String htmlCodeCoverage(final List<String> pathList, final List<String> s
935938
sb.append(StringTools.getCSV(excludeObjectList,16));
936939
sb.append(" ),\n");
937940
}
938-
sb.append(" a_reporter => ut_coverage_html_reporter()\n");
941+
sb.append(" a_reporter => ut_coverage_html_reporter(\n");
942+
sb.append(" a_html_report_assets_path => '");
943+
if (htmlReportAssetPath !=null) {
944+
// empty string is handled as NULL in Oracle Database
945+
sb.append(htmlReportAssetPath.toExternalForm());
946+
}
947+
sb.append("'\n");
948+
sb.append(" )\n");
939949
sb.append(" )\n");
940950
sb.append(" )");
941951
finalStringsql =sb.toString();

‎sqldev/src/main/java/org/utplsql/sqldev/runner/UtplsqlRunner.java

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
importjava.awt.Dimension;
1919
importjava.awt.Toolkit;
20+
importjava.net.URL;
2021
importjava.sql.Connection;
2122
importjava.text.SimpleDateFormat;
2223
importjava.util.Date;
@@ -71,24 +72,28 @@ public class UtplsqlRunner implements RealtimeReporterEventConsumer {
7172
privateThreadproducerThread;
7273
privateThreadconsumerThread;
7374
privatebooleandebug =false;
75+
privatefinalURLhtmlReportAssetPath;
7476

7577
publicUtplsqlRunner(finalList<String>pathList,finalStringconnectionName) {
7678
this.withCodeCoverage =false;
7779
this.pathList =pathList;
7880
this.schemaList =null;
7981
this.includeObjectList =null;
8082
this.excludeObjectList =null;
83+
this.htmlReportAssetPath =null;
8184
setConnection(connectionName);
8285
this.context =Context.newIdeContext();
8386
}
8487

8588
publicUtplsqlRunner(finalList<String>pathList,finalList<String>schemaList,
86-
finalList<String>includeObjectList,finalList<String>excludeObjectList,finalStringconnectionName) {
89+
finalList<String>includeObjectList,finalList<String>excludeObjectList,
90+
finalURLhtmlReportAssetPath,finalStringconnectionName) {
8791
this.withCodeCoverage =true;
8892
this.pathList =pathList;
8993
this.schemaList =schemaList;
9094
this.includeObjectList =includeObjectList;
9195
this.excludeObjectList =excludeObjectList;
96+
this.htmlReportAssetPath =htmlReportAssetPath;
9297
setConnection(connectionName);
9398
this.context =Context.newIdeContext();
9499
}
@@ -102,21 +107,23 @@ public UtplsqlRunner(final List<String> pathList, final Connection producerConn,
102107
this.schemaList =null;
103108
this.includeObjectList =null;
104109
this.excludeObjectList =null;
110+
this.htmlReportAssetPath =null;
105111
this.producerConn =producerConn;
106112
this.consumerConn =consumerConn;
107113
}
108114

109115
/**
110-
* this constructor is intended for tests only (with code coverage)
116+
* this constructor is intended for tests only (with code coverage and default htmlReportAssetPath)
111117
*/
112118
publicUtplsqlRunner(finalList<String>pathList,finalList<String>schemaList,
113-
finalList<String>includeObjectList,finalList<String>excludeObjectList,finalConnectionproducerConn,
114-
finalConnectionconsumerConn) {
119+
finalList<String>includeObjectList,finalList<String>excludeObjectList,
120+
finalConnectionproducerConn,finalConnectionconsumerConn) {
115121
this.withCodeCoverage =true;
116122
this.pathList =pathList;
117123
this.schemaList =schemaList;
118124
this.includeObjectList =includeObjectList;
119125
this.excludeObjectList =excludeObjectList;
126+
this.htmlReportAssetPath =null;
120127
this.producerConn =producerConn;
121128
this.consumerConn =consumerConn;
122129
}
@@ -314,7 +321,7 @@ private void produce() {
314321
logger.fine(() ->"Running utPLSQL tests and producing events via reporter id " +realtimeReporterId +"...");
315322
finalRealtimeReporterDaodao =newRealtimeReporterDao(producerConn);
316323
if (withCodeCoverage) {
317-
dao.produceReportWithCoverage(realtimeReporterId,coverageReporterId,pathList,schemaList,includeObjectList,excludeObjectList);
324+
dao.produceReportWithCoverage(realtimeReporterId,coverageReporterId,pathList,schemaList,includeObjectList,excludeObjectList,htmlReportAssetPath);
318325
}else {
319326
if (!debug) {
320327
dao.produceReport(realtimeReporterId,pathList);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp