diff --git a/.github/workflows/export_rules.yml b/.github/workflows/export_rules.yml new file mode 100644 index 00000000..202e9032 --- /dev/null +++ b/.github/workflows/export_rules.yml @@ -0,0 +1,60 @@ +name: Export rules + +on: + push: + branches: + - main + paths-ignore: + - "*.md" + - ".github/**/*.yml" + tags: + - "[0-9]+.[0-9]+.[0-9]+" + +jobs: + export: + name: Export + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up JDK 11 + uses: actions/setup-java@v4 + with: + distribution: "temurin" + java-version: 11 + cache: "maven" + + - name: Build + run: mvn -e -B install && mvn -e -B package -f tools/rule-exporter/pom.xml + + - name: Retrieve current version + id: version + run: | + echo "version=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout)" >> $GITHUB_OUTPUT + + - name: Export + run: | + mkdir -p dist && \ + java -jar ./tools/rule-exporter/target/rule-exporter-${{ steps.version.outputs.version }}.jar \ + ./target/creedengo-rules-specifications-${{ steps.version.outputs.version }}.jar \ + ./dist/rules.json + + - name: Archive artifacts + uses: actions/upload-pages-artifact@v3 + with: + path: ./dist + + deploy: + needs: export + permissions: + pages: write # to deploy to Pages + id-token: write # to verify the deployment originates from an appropriate source + environment: + name: rules + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 diff --git a/pom.xml b/pom.xml index 1723df1c..5cf7367e 100644 --- a/pom.xml +++ b/pom.xml @@ -1,5 +1,6 @@ - + 4.0.0 org.green-code-initiative @@ -133,7 +134,6 @@ UTF-8 ${encoding} ${encoding} - diff --git a/tools/rule-exporter/pom.xml b/tools/rule-exporter/pom.xml new file mode 100644 index 00000000..4ee2e091 --- /dev/null +++ b/tools/rule-exporter/pom.xml @@ -0,0 +1,101 @@ + + + 4.0.0 + + org.green-code-initiative + rule-exporter + ${revision} + + GCI Rule Exporter + Export all rules to JSON files usable by the website + https://github.com/green-code-initiative/creedengo-rules-specifications/tree/main/tools/rule-exporter + 2024 + + + 11 + ${java.version} + ${java.version} + true + true + + 2.1.3 + 2.0.1 + 5.10.1 + 3.25.3 + + + + + jakarta.json + jakarta.json-api + ${version.jakarta-json-api} + + + + org.glassfish + jakarta.json + ${version.jakarta-json} + module + + + + org.junit.jupiter + junit-jupiter + ${version.junit} + test + + + + org.assertj + assertj-core + ${version.assertj} + test + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.11.0 + + + org.apache.maven.plugins + maven-jar-plugin + 3.3.0 + + + + true + io.ecocode.tools.exporter.RuleExporter + + + + + + org.apache.maven.plugins + maven-shade-plugin + 3.5.0 + + + package + + shade + + + false + true + false + + + + + + maven-surefire-plugin + 3.1.2 + + + + diff --git a/tools/rule-exporter/src/main/java/org/greencodeinitiative/tools/exporter/RuleExporter.java b/tools/rule-exporter/src/main/java/org/greencodeinitiative/tools/exporter/RuleExporter.java new file mode 100644 index 00000000..19948760 --- /dev/null +++ b/tools/rule-exporter/src/main/java/org/greencodeinitiative/tools/exporter/RuleExporter.java @@ -0,0 +1,38 @@ +/* + * ecoCode Rule Exporter - Export all rules to JSON files usable by the website + * Copyright © 2024 Green Code Initiative (https://www.ecocode.io) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.greencodeinitiative.tools.exporter; + +import org.greencodeinitiative.tools.exporter.infra.RuleReader; +import org.greencodeinitiative.tools.exporter.infra.RuleWriter; + +import java.io.IOException; + +public class RuleExporter { + + public static void main(String[] args) throws IOException { + if (args.length != 2) { + System.out.println("Usage: java -jar rule-exporter.jar "); + System.exit(1); + } + + RuleReader reader = new RuleReader(args[0]); + RuleWriter writer = new RuleWriter(args[1]); + writer.writeRules(reader.readRules()); + } + +} diff --git a/tools/rule-exporter/src/main/java/org/greencodeinitiative/tools/exporter/domain/RuleId.java b/tools/rule-exporter/src/main/java/org/greencodeinitiative/tools/exporter/domain/RuleId.java new file mode 100644 index 00000000..b89bfa84 --- /dev/null +++ b/tools/rule-exporter/src/main/java/org/greencodeinitiative/tools/exporter/domain/RuleId.java @@ -0,0 +1,67 @@ +/* + * ecoCode Rule Exporter - Export all rules to JSON files usable by the website + * Copyright © 2024 Green Code Initiative (https://www.ecocode.io) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.greencodeinitiative.tools.exporter.domain; + +import java.util.Objects; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class RuleId implements Comparable { + + private static final Pattern PATTERN = Pattern.compile("^GCI(\\d+)$"); + + private final String naturalId; + + private final long id; + + public RuleId(String naturalId) { + Matcher matcher = PATTERN.matcher(naturalId); + if (matcher.find()) { + this.naturalId = naturalId; + this.id = Long.parseLong(matcher.group(1)); + } else { + throw new IllegalArgumentException("Invalid rule id: " + naturalId); + } + } + + @Override + public String toString() { + return this.naturalId; + } + + @Override + public int compareTo(RuleId o) { + return Long.compare(this.id, o.id); + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + RuleId ruleId = (RuleId) o; + return id == ruleId.id; + } + + @Override + public int hashCode() { + return Objects.hash(id); + } + +} diff --git a/tools/rule-exporter/src/main/java/org/greencodeinitiative/tools/exporter/domain/RuleMetadata.java b/tools/rule-exporter/src/main/java/org/greencodeinitiative/tools/exporter/domain/RuleMetadata.java new file mode 100644 index 00000000..26e00d4a --- /dev/null +++ b/tools/rule-exporter/src/main/java/org/greencodeinitiative/tools/exporter/domain/RuleMetadata.java @@ -0,0 +1,106 @@ +/* + * ecoCode Rule Exporter - Export all rules to JSON files usable by the website + * Copyright © 2024 Green Code Initiative (https://www.ecocode.io) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.greencodeinitiative.tools.exporter.domain; + +public class RuleMetadata { + + private final RuleId id; + private final String technology; + private final String title; + private final RuleSeverity severity; + private final RuleStatus status; + + private RuleMetadata(String id, String technology, String title, RuleSeverity severity, RuleStatus status) { + this.id = new RuleId(id); + this.technology = technology; + this.title = title; + this.severity = severity; + this.status = status; + } + + public RuleId getId() { + return this.id; + } + + public String getTechnology() { + return this.technology; + } + + public String getTitle() { + return this.title; + } + + public RuleSeverity getSeverity() { + return this.severity; + } + + public RuleStatus getStatus() { + return this.status; + } + + @Override + public String toString() { + return "RuleMetadata{" + + "id='" + id + '\'' + + ", language='" + technology + '\'' + + ", title='" + title + '\'' + + ", severity=" + severity + + ", status=" + status + + '}'; + } + + public static class Builder { + + private String id; + private String technology; + private String title; + private RuleSeverity severity; + private RuleStatus status; + + public Builder id(String id) { + this.id = id; + return this; + } + + public Builder technology(String technology) { + this.technology = technology; + return this; + } + + public Builder title(String title) { + this.title = title; + return this; + } + + public Builder severity(RuleSeverity severity) { + this.severity = severity; + return this; + } + + public Builder status(RuleStatus status) { + this.status = status; + return this; + } + + public RuleMetadata build() { + return new RuleMetadata(id, technology, title, severity, status); + } + + } + +} diff --git a/tools/rule-exporter/src/main/java/org/greencodeinitiative/tools/exporter/domain/RuleSeverity.java b/tools/rule-exporter/src/main/java/org/greencodeinitiative/tools/exporter/domain/RuleSeverity.java new file mode 100644 index 00000000..56e58fec --- /dev/null +++ b/tools/rule-exporter/src/main/java/org/greencodeinitiative/tools/exporter/domain/RuleSeverity.java @@ -0,0 +1,22 @@ +/* + * ecoCode Rule Exporter - Export all rules to JSON files usable by the website + * Copyright © 2024 Green Code Initiative (https://www.ecocode.io) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.greencodeinitiative.tools.exporter.domain; + +public enum RuleSeverity { + INFO, MINOR, MAJOR, CRITICAL +} diff --git a/tools/rule-exporter/src/main/java/org/greencodeinitiative/tools/exporter/domain/RuleStatus.java b/tools/rule-exporter/src/main/java/org/greencodeinitiative/tools/exporter/domain/RuleStatus.java new file mode 100644 index 00000000..0a14fbff --- /dev/null +++ b/tools/rule-exporter/src/main/java/org/greencodeinitiative/tools/exporter/domain/RuleStatus.java @@ -0,0 +1,22 @@ +/* + * ecoCode Rule Exporter - Export all rules to JSON files usable by the website + * Copyright © 2024 Green Code Initiative (https://www.ecocode.io) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.greencodeinitiative.tools.exporter.domain; + +public enum RuleStatus { + READY, DEPRECATED +} diff --git a/tools/rule-exporter/src/main/java/org/greencodeinitiative/tools/exporter/infra/JsonMapper.java b/tools/rule-exporter/src/main/java/org/greencodeinitiative/tools/exporter/infra/JsonMapper.java new file mode 100644 index 00000000..8c492e7c --- /dev/null +++ b/tools/rule-exporter/src/main/java/org/greencodeinitiative/tools/exporter/infra/JsonMapper.java @@ -0,0 +1,52 @@ +/* + * ecoCode Rule Exporter - Export all rules to JSON files usable by the website + * Copyright © 2024 Green Code Initiative (https://www.ecocode.io) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.greencodeinitiative.tools.exporter.infra; + +import org.greencodeinitiative.tools.exporter.domain.RuleMetadata; +import org.greencodeinitiative.tools.exporter.domain.RuleSeverity; +import org.greencodeinitiative.tools.exporter.domain.RuleStatus; +import jakarta.json.JsonObject; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class JsonMapper { + + private static final Pattern FILE_PATTERN = Pattern + .compile("^org/green-code-initiative/rules/(.*?)/(.*?)\\.json$"); + + public static RuleMetadata toRuleMetadata(String filePath, JsonObject object) { + Matcher fileMatcher = FILE_PATTERN.matcher(filePath); + + if (!fileMatcher.find() || fileMatcher.groupCount() != 2) { + throw new IllegalStateException("Invalid file path: " + filePath); + } + + RuleSeverity severity = RuleSeverity.valueOf(object.getString("defaultSeverity").toUpperCase()); + RuleStatus status = RuleStatus.valueOf(object.getString("status").toUpperCase()); + + return new RuleMetadata.Builder() + .id(fileMatcher.group(2)) + .technology(fileMatcher.group(1)) + .title(object.getString("title")) + .severity(severity) + .status(status) + .build(); + } + +} diff --git a/tools/rule-exporter/src/main/java/org/greencodeinitiative/tools/exporter/infra/RuleReader.java b/tools/rule-exporter/src/main/java/org/greencodeinitiative/tools/exporter/infra/RuleReader.java new file mode 100644 index 00000000..d55ff64c --- /dev/null +++ b/tools/rule-exporter/src/main/java/org/greencodeinitiative/tools/exporter/infra/RuleReader.java @@ -0,0 +1,87 @@ +/* + * ecoCode Rule Exporter - Export all rules to JSON files usable by the website + * Copyright © 2024 Green Code Initiative (https://www.ecocode.io) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.greencodeinitiative.tools.exporter.infra; + +import org.greencodeinitiative.tools.exporter.domain.RuleMetadata; +import jakarta.json.Json; +import jakarta.json.JsonObject; +import jakarta.json.JsonReader; + +import java.io.File; +import java.io.FilterInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.stream.Collectors; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; + +public class RuleReader { + + private final String zipFilename; + + public RuleReader(String zipFilename) { + this.zipFilename = zipFilename; + } + + private static FilterInputStream getContentsInFile(ZipInputStream inputStream) { + return new FilterInputStream(inputStream) { + @Override + public void close() throws IOException { + inputStream.closeEntry(); + } + }; + } + + public Collection readRules() throws IOException { + return readAllMetadataFromZip().entrySet().stream() + .map(entry -> JsonMapper.toRuleMetadata(entry.getKey(), entry.getValue())) + .collect(Collectors.toSet()); + } + + private Map readAllMetadataFromZip() throws IOException { + Map metadataMap = new HashMap<>(); + Path path = new File(zipFilename).toPath(); + try ( + InputStream inputStream = Files.newInputStream(path); + ZipInputStream zipIn = new ZipInputStream(inputStream)) { + ZipEntry entry; + + while ((entry = zipIn.getNextEntry()) != null) { + if (!entry.getName().endsWith(".json") || entry.getName().startsWith("__MACOSX")) { + zipIn.closeEntry(); + continue; + } + metadataMap.put(entry.getName(), readContents(getContentsInFile(zipIn))); + } + } + + return metadataMap; + } + + private JsonObject readContents(InputStream contentsIn) { + try (JsonReader reader = Json.createReader(contentsIn)) { + return reader.readObject(); + } + } + +} diff --git a/tools/rule-exporter/src/main/java/org/greencodeinitiative/tools/exporter/infra/RuleWriter.java b/tools/rule-exporter/src/main/java/org/greencodeinitiative/tools/exporter/infra/RuleWriter.java new file mode 100644 index 00000000..d83751ba --- /dev/null +++ b/tools/rule-exporter/src/main/java/org/greencodeinitiative/tools/exporter/infra/RuleWriter.java @@ -0,0 +1,95 @@ +/* + * ecoCode Rule Exporter - Export all rules to JSON files usable by the website + * Copyright © 2024 Green Code Initiative (https://www.ecocode.io) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.greencodeinitiative.tools.exporter.infra; + +import org.greencodeinitiative.tools.exporter.domain.RuleId; +import org.greencodeinitiative.tools.exporter.domain.RuleMetadata; +import jakarta.json.Json; +import jakarta.json.JsonArray; +import jakarta.json.JsonObject; +import jakarta.json.JsonWriter; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; + +public class RuleWriter { + + private final String outputFilename; + + public RuleWriter(String outputFilename) { + this.outputFilename = outputFilename; + } + + public void writeRules(Collection rules) throws IOException { + Path path = new File(outputFilename).toPath(); + try (JsonWriter resultJsonWriter = Json.createWriter(Files.newBufferedWriter(path))) { + resultJsonWriter.writeObject( + Json.createObjectBuilder() + .add("items", buildItems(rules)) + .add("meta", buildMeta(rules)) + .build()); + } + } + + private JsonArray buildItems(Collection rules) { + Map> rulesById = rules.stream().collect(Collectors.groupingBy(RuleMetadata::getId)); + return Json.createArrayBuilder( + rulesById.entrySet().stream() + .sorted(Map.Entry.comparingByKey()) + .map(e -> this.buildItem(e.getValue())) + .collect(Collectors.toList())) + .build(); + } + + private JsonObject buildItem(Collection rulesById) { + RuleMetadata first = rulesById.iterator().next(); + return Json.createObjectBuilder() + .add("id", first.getId().toString()) + .add("name", first.getTitle()) + .add("severity", first.getSeverity().toString()) + .add("technologies", extractAllProperties(rulesById, RuleMetadata::getTechnology)) + .add("status", first.getStatus().toString()) + .build(); + } + + private JsonObject buildMeta(Collection rules) { + return Json.createObjectBuilder() + .add("technologies", extractAllProperties(rules, RuleMetadata::getTechnology)) + .add("severities", extractAllProperties(rules, rule -> rule.getSeverity().toString())) + .add("statuses", extractAllProperties(rules, rule -> rule.getStatus().toString())) + .build(); + } + + private JsonArray extractAllProperties(Collection rules, Function mapper) { + return Json.createArrayBuilder( + rules.stream() + .map(mapper) + .distinct() + .sorted() + .collect(Collectors.toList())) + .build(); + } + +} diff --git a/tools/rule-exporter/src/test/java/org/greencodeinitiative/tools/exporter/domain/RuleIdTest.java b/tools/rule-exporter/src/test/java/org/greencodeinitiative/tools/exporter/domain/RuleIdTest.java new file mode 100644 index 00000000..cece65c1 --- /dev/null +++ b/tools/rule-exporter/src/test/java/org/greencodeinitiative/tools/exporter/domain/RuleIdTest.java @@ -0,0 +1,72 @@ +/* + * ecoCode Rule Exporter - Export all rules to JSON files usable by the website + * Copyright © 2024 Green Code Initiative (https://www.ecocode.io) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.greencodeinitiative.tools.exporter.domain; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.fail; + +public class RuleIdTest { + + @Test + void valid() { + RuleId rule1 = new RuleId("GCI1"); + RuleId rule956 = new RuleId("GCI956"); + + assertThat(rule1.toString()).isEqualTo("GCI1"); + assertThat(rule956.toString()).isEqualTo("GCI956"); + } + + @Test + void invalid() { + try { + new RuleId("GCI"); + fail("Should throw exception"); + } catch (IllegalArgumentException e) { + assertThat(e.getMessage()).isEqualTo("Invalid rule id: GCI"); + } + + try { + new RuleId("INVALID"); + fail("Should throw exception"); + } catch (IllegalArgumentException e) { + assertThat(e.getMessage()).isEqualTo("Invalid rule id: INVALID"); + } + } + + @Test + void equals() { + RuleId rule1 = new RuleId("GCI1"); + assertThat(rule1).isEqualTo(new RuleId("GCI1")); + assertThat(rule1).isNotEqualTo(new RuleId("GCI956")); + } + + @Test + void _hashCode() { + assertThat(new RuleId("GCI1").hashCode()).isEqualTo(new RuleId("GCI1").hashCode()); + } + + @Test + void comparison() { + assertThat(new RuleId("GCI5").compareTo(new RuleId("GCI6"))).isLessThan(0); + assertThat(new RuleId("GCI5").compareTo(new RuleId("GCI5"))).isZero(); + assertThat(new RuleId("GCI6").compareTo(new RuleId("GCI5"))).isGreaterThan(0); + } + +} diff --git a/tools/rule-exporter/src/test/java/org/greencodeinitiative/tools/exporter/domain/RuleMetadataTest.java b/tools/rule-exporter/src/test/java/org/greencodeinitiative/tools/exporter/domain/RuleMetadataTest.java new file mode 100644 index 00000000..4b6ddf4e --- /dev/null +++ b/tools/rule-exporter/src/test/java/org/greencodeinitiative/tools/exporter/domain/RuleMetadataTest.java @@ -0,0 +1,55 @@ +/* + * ecoCode Rule Exporter - Export all rules to JSON files usable by the website + * Copyright © 2024 Green Code Initiative (https://www.ecocode.io) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.greencodeinitiative.tools.exporter.domain; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +public class RuleMetadataTest { + + private RuleMetadata ruleMetadata; + + @BeforeEach + void setUp() { + ruleMetadata = new RuleMetadata.Builder() + .id("GCI10") + .technology("java") + .title("title") + .severity(RuleSeverity.INFO) + .status(RuleStatus.READY) + .build(); + } + + @Test + void builder() { + assertThat(ruleMetadata.getId()).isEqualTo(new RuleId("GCI10")); + assertThat(ruleMetadata.getTechnology()).isEqualTo("java"); + assertThat(ruleMetadata.getTitle()).isEqualTo("title"); + assertThat(ruleMetadata.getSeverity()).isEqualTo(RuleSeverity.INFO); + assertThat(ruleMetadata.getStatus()).isEqualTo(RuleStatus.READY); + } + + @Test + void asString() { + assertThat(ruleMetadata.toString()).isEqualTo( + "RuleMetadata{id='GCI10', language='java', title='title', severity=INFO, status=READY}"); + } + +} diff --git a/tools/rule-exporter/src/test/java/org/greencodeinitiative/tools/exporter/infra/RuleReaderTest.java b/tools/rule-exporter/src/test/java/org/greencodeinitiative/tools/exporter/infra/RuleReaderTest.java new file mode 100644 index 00000000..d8093ef7 --- /dev/null +++ b/tools/rule-exporter/src/test/java/org/greencodeinitiative/tools/exporter/infra/RuleReaderTest.java @@ -0,0 +1,69 @@ +/* + * ecoCode Rule Exporter - Export all rules to JSON files usable by the website + * Copyright © 2024 Green Code Initiative (https://www.ecocode.io) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.greencodeinitiative.tools.exporter.infra; + +import org.greencodeinitiative.tools.exporter.domain.RuleId; +import org.greencodeinitiative.tools.exporter.domain.RuleMetadata; +import org.greencodeinitiative.tools.exporter.domain.RuleSeverity; +import org.greencodeinitiative.tools.exporter.domain.RuleStatus; +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.util.Collection; +import java.util.Objects; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.fail; + +public class RuleReaderTest { + + @Test + void validRules() throws IOException { + RuleReader ruleReader = new RuleReader(getFilePath("rules.jar")); + Collection rules = ruleReader.readRules(); + + // check rules count + assertThat(rules).isNotNull().hasSize(10); + + // check a specific rule + RuleMetadata ruleEC3 = rules.stream().filter(r -> r.getId().toString().equals("GCI3")).findFirst() + .orElseGet(() -> fail("GCI3 rule not found")); + + assertThat(ruleEC3.getId()).isEqualTo(new RuleId("GCI3")); + assertThat(ruleEC3.getTitle()).isEqualTo("Avoid getting the size of the collection in the loop"); + assertThat(ruleEC3.getTechnology()).isEqualTo("java"); + assertThat(ruleEC3.getSeverity()).isEqualTo(RuleSeverity.MINOR); + assertThat(ruleEC3.getStatus()).isEqualTo(RuleStatus.READY); + } + + @Test + void invalidRules() throws IOException { + RuleReader ruleReader = new RuleReader(getFilePath("invalid-rules.jar")); + try { + ruleReader.readRules(); + fail("Exception not thrown"); + } catch (IllegalStateException e) { + assertThat(e.getMessage()).isEqualTo("Invalid file path: org/green-code-initiative/rules/invalid.json"); + } + } + + private String getFilePath(String fileName) { + return Objects.requireNonNull(getClass().getResource("/" + fileName)).getPath(); + } + +} diff --git a/tools/rule-exporter/src/test/java/org/greencodeinitiative/tools/exporter/infra/RuleWriterTest.java b/tools/rule-exporter/src/test/java/org/greencodeinitiative/tools/exporter/infra/RuleWriterTest.java new file mode 100644 index 00000000..aef054ec --- /dev/null +++ b/tools/rule-exporter/src/test/java/org/greencodeinitiative/tools/exporter/infra/RuleWriterTest.java @@ -0,0 +1,76 @@ +/* + * ecoCode Rule Exporter - Export all rules to JSON files usable by the website + * Copyright © 2024 Green Code Initiative (https://www.ecocode.io) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.greencodeinitiative.tools.exporter.infra; + +import org.greencodeinitiative.tools.exporter.domain.RuleMetadata; +import org.greencodeinitiative.tools.exporter.domain.RuleSeverity; +import org.greencodeinitiative.tools.exporter.domain.RuleStatus; +import jakarta.json.Json; +import jakarta.json.JsonObject; +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Collection; + +import static org.assertj.core.api.Assertions.assertThat; + +public class RuleWriterTest { + + private static final Path TARGET_PATH = Paths.get("target/rules.json"); + + @Test + void writeRules() throws IOException { + Collection rules = new ArrayList<>(); + + RuleMetadata rule1 = new RuleMetadata.Builder() + .id("GCI1") + .title("Respect the planet") + .technology("java") + .severity(RuleSeverity.CRITICAL) + .status(RuleStatus.READY) + .build(); + + RuleMetadata rule2 = new RuleMetadata.Builder() + .id("GCI2") + .title("Recycle whenever possible") + .technology("javascript") + .severity(RuleSeverity.MAJOR) + .status(RuleStatus.READY) + .build(); + + rules.add(rule1); + rules.add(rule2); + + RuleWriter ruleWriter = new RuleWriter(TARGET_PATH.toString()); + ruleWriter.writeRules(rules); + + InputStream expectedStream = getClass().getResourceAsStream("/expected-rules.json"); + assertThat(expectedStream).isNotNull(); + + JsonObject expectedObject = Json.createReader(expectedStream).readObject(); + JsonObject actualObject = Json.createReader(Files.newBufferedReader(TARGET_PATH)).readObject(); + + assertThat(actualObject).isEqualTo(expectedObject); + } + +} diff --git a/tools/rule-exporter/src/test/resources/expected-rules.json b/tools/rule-exporter/src/test/resources/expected-rules.json new file mode 100644 index 00000000..46716067 --- /dev/null +++ b/tools/rule-exporter/src/test/resources/expected-rules.json @@ -0,0 +1,23 @@ +{ + "items": [ + { + "id": "GCI1", + "name": "Respect the planet", + "severity": "CRITICAL", + "technologies": ["java"], + "status": "READY" + }, + { + "id": "GCI2", + "name": "Recycle whenever possible", + "severity": "MAJOR", + "technologies": ["javascript"], + "status": "READY" + } + ], + "meta": { + "technologies": ["java", "javascript"], + "severities": ["CRITICAL", "MAJOR"], + "statuses": ["READY"] + } +} diff --git a/tools/rule-exporter/src/test/resources/invalid-rules.jar b/tools/rule-exporter/src/test/resources/invalid-rules.jar new file mode 100644 index 00000000..cc37449c Binary files /dev/null and b/tools/rule-exporter/src/test/resources/invalid-rules.jar differ diff --git a/tools/rule-exporter/src/test/resources/rules.jar b/tools/rule-exporter/src/test/resources/rules.jar new file mode 100644 index 00000000..423b72e0 Binary files /dev/null and b/tools/rule-exporter/src/test/resources/rules.jar differ