Hi,
when running unit tests, I need to manipulate SVG files. I’m using the official JSVG library, not the modified version that’s integrated into IntelliJ.
With the IntelliJ platform plugin v2.1.0, everything work fine.
With the IntelliJ platform plugin v2.2.0+, the test classpath is altered by the IntelliJ platform plugin: it’s using the JSVG classes that comes with the IDE. Unfortunately, this version diverged from the official JSVG (some classes are absent or not public), which breaks my tests.
Do you know how to use the official JSVG library when running unit tests?
Thanks.
Is this issue still valid with the IntelliJ Platform Gradle Plugin 2.5.0?
I still have the same problem with the IntelliJ Platform Gradle Plugin 2.5.0.
@jonathanlermitage.1 In the Plugin Template, I added
dependencies {
implementation("com.github.weisj:jsvg:1.7.0")
}
and the following test:
fun testSvg() {
SVGLoader().load(javaClass.getResource("/foo.svg"))!!.viewBox()
}
The targeted IntelliJ Platform 2024.2.5
contains the SVGDocument
class in a version with no viewBox()
method, but tests are green anyway, meaning the correct library is used.
Try
SVGDocument svgDocument = new SVGLoader().load(new ByteArrayInputStream(FileUtil.loadFileBytes(aFile)));
and you will get a
java.lang.NoSuchMethodError: 'void com.github.weisj.jsvg.parser.LoadHelper.<init>(com.github.weisj.jsvg.attributes.AttributeParser, com.github.weisj.jsvg.parser.LoaderContext)'
at com.github.weisj.jsvg.parser.SVGDocumentBuilder.<init>(SVGDocumentBuilder.java:72)
at com.github.weisj.jsvg.parser.StaxSVGLoader.parse(StaxSVGLoader.java:107)
at com.github.weisj.jsvg.parser.StaxSVGLoader.load(StaxSVGLoader.java:176)
at com.github.weisj.jsvg.parser.SVGLoader.load(SVGLoader.java:111)
If you look at the LoadHelper class:
- from IJ sources: there is one constructor
- from the official library: there are two constructors
My full test:
List<String> errors = new ArrayList<>();
for (File file : svgIcons) { // a list of all my icons
try {
SVGDocument svgDocument = new SVGLoader().load(new ByteArrayInputStream(FileUtil.loadFileBytes(file)), null, LoaderContext.createDefault());
if (svgDocument == null) {
errors.add(file.getName() + ": can't be loaded by JSVG. Loaded SVGDocument is null");
} else {
FloatSize size = svgDocument.size();
BufferedImage image = ImageUtil.createImage((int) size.getWidth(), (int) size.getHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics2D graphics = image.createGraphics();
svgDocument.render(null, graphics);
Image thumbnail = ImageUtil.scaleImage(image, 1.25f);
if (thumbnail == null) {
errors.add(file.getName() + ": can't be loaded by JSVG. Generated thumbnail is null");
}
}
} catch (IOException e) {
errors.add(file.getName() + ": can't be loaded by JSVG. I/O error is: " + e.getMessage());
}
}
if (!errors.isEmpty()) {
fail("some SVG icons did not load: " + arrayToString(errors));
}
This works because JSVG is an implementation
. If you move it to testImplementation
, you get an error saying Unresolved reference 'viewBox'
.
I need testImplementation
because I want to check my icons, but only during my tests. I don’t want to bundle my own JSVG with my plugin.
Ideally (or, as a workaround), I would test with the JSVG code that comes with the IDE, but I found no public constructor or methods that fit my needs: load SVG files, and resize them, because this is what my plugin does all the time. This was a long time ago (when the JSVG fork had been incorporated into the IDE). I’m checking regularly, without success.
Could you please try the 2.5.1-SNAPSHOT
?
1 Like
This works perfectly. Thank you!